My question stems from this process: Assume an application has a host or address field and would like to connect to some service at that address. Many applications will look at that address and guess if it is an ip address or a host name. This application may use a function like inet_pton() to do this checking. If the address does look like an ip address, the application would not perform a DNS lookup and use that ip address directly.
Now, I am not suggesting this is a good idea but what if some one defined a dns name that looked like 1.2.3.4. That looks like an ip address so the application above would use that as and ip address and not as a DNS name.
From observation, it seems most applications behave as described in the first paragraph. Which seems beneficial for a few reasons to me. Is there any documentation that states that DNS names that look like IP addresses should not be used. Or any documentation that says that even if some one defined a DNS name to look like an IP address it is OK to not honor it as such.
Others have answered already but I'll add and consolidate.
Relevant RFCs:
https://www.rfc-editor.org/rfc/rfc952 (Original)
https://www.rfc-editor.org/rfc/rfc1123 (Revised)
https://www.rfc-editor.org/rfc/rfc2606 (Extra)
Originally, a hostname could not begin with a number, to disambiguate between hostnames and IP addresses. In the revision, that was changed, and hostnames can begin with a number. Thus, domain names like 127.0.0.1.com are legal. TLDs cannot begin with a number (TLD stands for top level domain, of which .com, .net, .org, country codes, and others are members). Names must contain at least one character, must begin and end with alphanumeric characters, and may freely be up to 64 characters long (though the standard supports longer hostnames, systems are not required to support names longer than 64 characters).
Additionally, as described in the final RFC, some SLDs and TLDs are reserved and cannot be registered.
The relevant specification to look at is Section 2.1 of RFC 1123:
If a dotted-decimal number can be entered without such identifying delimiters, then a full syntactic check must be made, because a segment of a host domain name is now allowed to begin with a digit and could legally be entirely numeric (see Section 6.1.2.4). However, a valid host name can never have the dotted-decimal form #.#.#.#, since at least the highest-level component label will be alphabetic.
Related
I am using RTI DDS 5.2.3.17 and would like to get the IP address of the DataWriter/Publisher to add to some log messages.
How would I go about doing this I am having some trouble in just forming the logic of what to do?
Accessing the IP address of a DataWriter is not possible in a standardized way. However, the RTI Connext implementation by default uses the IP address as part of every Entity's Globally Unique Identifier (GUID).
You can find more information about GUIDs and how to access them in the RTI Knowledge Base article Accessing the GUID of Connext DDS Entities. Normally, the IP address is captured in the first 4 bytes of the GUID, indicated by rtps_host_id in the DDS_GUID_t diagram.
You did not explain your situation in too much detail, but if you happen to have data available coming from the DataWriter, you could also leverage the SampleInfo that comes with the data. It has a field called source_guid.
All of this is assuming you are looking for the IPv4 address. Also note that this is not a publicly exposed mechanism, so things might change in the future. And all of this breaks at the moment that your application explicitly sets its GUID.
The DataWriter GUID is not a reliable way to get the IP address of the DomainParticipant. More recent versions of Connext DDS no longer construct the GUID_t from the IP address or the host ID.
A right way is to look at the ParticipantBultinTopicData of the DomainParticipant that owns that DataWriter. The field default_unicast_locators contains the IP addresses of the DomainParticipant.
You can get the ParticipantBultinTopicData of the DomainParticipant that owns the DataWriter that wrote a sample from theSampleInfo. To do this call get_matched_publication_participant_data() on the DataReader passing the publication_handle that is found in the SampleInfo.
Note that the above gets you the IP addresses (Locators) of the DomainParticipant that owns the DataWriter. It is possible for a DataWriter to override those and provide a different set (normally a subset). This probably does not matter if you just want to provide logging. But if you wanted to see if the DataWriter uses a different set of Locators you can also get those from the unicast_locators field in the PublicationBuiltinTopicData which you can also get from the SampleInfo calling get_matched_publication_data().
My reading of dig's manpage isn't answering this question. Is there a set of command-line options to dig such that I can type
dig $WHATEVER my-aname.example.com
and have it do a forward lookup for that host's IP and then have it reverse-resolve that IP to the server's canonical name(s)?
You can't do that in a single lookup. In any event the definition of a canonical hostname is not as well defined as you would need.
For example, the right-hand side of a CNAME record was originally supposed to point to a canonical name, but often doesn't (so-called "CNAME chaining").
An IP address can also have multiple PTR records, there's no requirement that there be one (singular) canonical name for an IP address.
Is 0.0.0.0 a valid IP address? I want my program to be able to store it as an indication that no address is in use, but this won't work if it's actually valid.
It is valid inasmuch as it contains four octets, each within the range 0 through 255 inclusive. However, it is not usable as a real IP address.
RFC1700 (a) states that 0.0.0.0/8 (0.<anything>.<anything>.<anything>) is reserved as a source address only. You can get into situation where it appears you have this address but that's normally because no address has been assigned to you (by DHCP, for example).
See also Wikipedia entry on IPv4.
(a) Although this RFC is now considered obsolete, it is still correct in terms of the given behaviour. Its replacement, https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml, still has the same text detailing use of the 0.0.0.0 address.
Lets look at the Question being asked here by the OP.
Is 0.0.0.0 a valid IP address?
Yes. This is technically a valid IP address, and the other answers describe many various uses of it (I am not going to repost wikipedia links here ... or maybe I am).
As such I believe paxdiablo's answer above is the most correct, but lets look at the context of your question as well.
I want my program to be able to store it as an indication that no address is in use, but this won't work if it's actually valid.
This entirely depends on your use case. Given that this is a programmers forum, lets consider that perspective.
If your software is storing actual internet addresses - server locations, visitors to your website, replication/mirror or backup sites, web service or database servers etc. - then this will be perfectly valid. No machine on the internet will ever have this address assigned, nor will it ever resolve to a valid connection.
If on the other hand you are writing firewall or router firmware, then this address does take on special meaning; default route, accept any IP source/destination, block all IP source/destination, fall-trough catch-all, etc. as outlined by everyone else. However, let me point out that if you are coding on this level you should have a good enough understanding of network protocols so as to not need to ask this question in the first place.
I am therefore going to assume that most people viewing this question fall into the first category, and suggest that this is a perfectly valid way of storing a null, empty or missing IP address, if there is some reason that an actual null value cannot be used. Even if you neglect validation checking and your software does try to connect to this IP address, it will simply not be able to make a connection.
The 0.0.0.0 is used to bind all IPv4 interfaces. So it's a special value just like 127.0.0.1.
Yes, it is an IP address but it is reserved.
0.0.0.0/8 - Addresses in this block refer to source hosts on "this"
network. Address 0.0.0.0/32 may be used as a source address for this
host on this network; other addresses within 0.0.0.0/8 may be used to
refer to specified hosts on this network
It's reserved as the default route address.
It's common to see this via ipconfig when no address has been assigned to you.
for all intents and purposes, yes. Each of the four numbers separated by the period have a value ranging from 0-255, so 0.0.0.0 is technically valid.
I don't think that there would be anyone in the world who actually has that IP though.
EDIT: okay, it is reserved for the default route, but it is still valid.
You can use it in your application to represent that it does not have an IP address, Microsoft also uses 0.0.0.0 when the machine has no IP address.
the "Valid" scenarios talked about above are dependent on the specific scenarios where they have nothing to do with your application.
Doing a Network Whois query can also produce output that is quite helpful.
Example:
http://whois.arin.net/rest/nets;q=0.0.0.0?showDetails=true
Comment: The address 0.0.0.0 may only be used as the address of an outgoing packet when a computer is learning which IP address it should use. It is never used as a destination address. Addresses starting with "0." are sometimes used for broadcasts to directly connected devices.
As other answers have covered, 0.0.0.0 is a legal and valid for some purposes IP address.
If all values in a range are legal values, then any flag items you want to define must come from somewhere else. Otherwise you will overload a legal value with the meaning of a flag, and when using the overloaded value it won't be 100% possible to determine whether the legal value or the flag meaning was intended. This will lead to bugs which must be solved with a re-factor which can be an expensive endeavour.
Overloading legal values happens all the time, IP address and MAC addresses (yes, 00:00:00:00:00:00 is legal and allocated) are some of the most common victims.
Coincidentally, I am working on a system (not ethernet/IP based) now where the length of a frame is capped at about 40 bytes. Since a byte can represent lengths of 0 - 255 bytes, and the max length is 40 bytes, I can use some of the unused aka non-legal values (252 to 255) to represent flag items. These in-band flags are okay because there is no overloading.
of course it is.
it will not be valid for a single host on a network however. it is in the broadcast range for the local network. read here: https://www.rfc-editor.org/rfc/rfc1700
In my application, I have to send notification e-mails from time to time. In order to send mail (over SMTP), I have to get the MX server of that particular domain (domain part of e-mail address). This is not a Unix application but an Embedded one.
What I do goes like this ::
1 - Send a DNS query (MX type) containing the domain to the current DNS
2 - If the response contains the MX answer , return success from this function
3 - Read the first NS record and copy its IP address to the current DNS , goto 1
This may loop a few times and this is expected but what I do not expect is that the response contains NS records of servers named like ns1.blahblah.com but not their IP addresses. In this case, I have to send another query to find the IP of this NS. I have seen this for only 1 e-mail address (1 domain), the other addresses worked without any problem.
Is this normal behaviour ? IMHO, it is a misconfig on the DNS records. Any thoughts ?
Thanks in advance...
The authority section in the message, as well as the additional section are optional. Ie, the name servers and their IPs don't have to be in the response to the MX query. It is up to the DNS server to decide to send that extra information even when the server already has the data.
You are stuck having to query for the MX and then query for the IP of the mail server
Short answer to your question: RFC 1035 says,
NS records cause both the usual additional section processing to locate
a type A record, and, when used in a referral, a special search of the
zone in which they reside for glue information.
...the additional records section contains RRs
which relate to the query, but are not strictly answers for the
question.
...When composing a response, RRs which are to be inserted in the
additional section, but duplicate RRs in the answer or authority
sections, may be omitted from the additional section.
So the bottom line in my opinion is that, yes, if the response does not contain the A record matching the NS record it some section, something is likely misconfigured somewhere. But, as the old dodge goes, "be liberal in what you accept;" if you are going to make the queries, you will need to handle situations like this. DNS is awash in these kinds of problems.
The longer answer requires a question: how are you getting the original DNS server where you are starting the MX lookup?
What you are doing is a non-recursive query: if the first server you query does not know the answer, it points you at another server that is "closer" in the DNS hierarchy to the domain you are looking for, and you have to make the subsequent queries to find the MX record. If you are starting your query at one of the root servers, I think you will have to follow the NS pointers yourself like you are.
However, if the starting DNS server is configured in your application (i.e. a manual configuration item or via DHCP), then you should be able to make a recursive request, using the Recusion Desired flag, which will push the repeated lookup off onto the configured DNS server. In that case you would just get the MX record value in your first response. On the other hand, recursive queries are optional, and your local DNS server may not support them (which would be bizarre since, historically, many client libraries relied on recursive lookups).
In any case, I would personally like to thank you for looking MX records. I have had to deal with systems that wanted to send mail but could not do the DNS lookups, and the number and variety of bizarre and unpleasant hacks they have used has left me with emotional scars.
It could be that the domain simply does not have a MX record. I completely take out the MX entry for my unused / parked domains, it saves my mail server a lot of grief (SPAM).
There really is no need to go past step 2. If the system (or ISP) resolver returned no MX entry, its because it already did the extra steps and found nothing. Or, possibly, the system host resolver is too slow (i.e. from an ISP).
Still, I think its appropriate to just bail out if either happened, as its clearly a DNS or ISP issue, not a problem with the function. Just tell the user that you could not resolve a MX record for the domain, and let them investigate it on their end.
Also, is it feasible to make the resolvers configurable in the application itself, so users could get around a bunky NS?
I'm working on a network client program that connects to public servers, specified by the user. If the user gives me a hostname to connect to that has both IPv4 and IPv6 addresses (commonly, a DNS name with both A and AAAA records), I'm not sure how I should decide which address I should connect to.
The problem is that it's quite common for machines to support both IPv4 and IPv6, but only to have global connectivity over IPv4. The most common case of this is when only IPv6 link-local addresses are configured. At the moment the best alternatives I can come up with are:
Try the IPv6 address(es) first - if the connection fails, try the IPv4 address(es); or
Just let the user specify it as a config setting ("prefer_ipv6" versus "prefer_ipv4").
The problem I can see with option 1 is that the connection might not fail straight away - it might take quite a while to time out.
Please do try IPv6. In the significant majority of installations, trying to create an IPv6 connection will fail right away if it can't succeed for some reason:
if the system doesn't support IPv6 sockets, creating the socket will fail
if the system does support IPv6, and has link-local addresses configured, there won't be any routing table entry for the global IPv6 addresses. Again, the local kernel will report failure without sending any packets.
if the system does have a global IP address, but some link necessary for routing is missing, the source should be getting an ICMPv6 error message, indicating that the destination cannot be reached; likewise if the destination has an IPv6 address, but the service isn't listening on it.
There are of course cases where things can break, e.g. if a global (or tunnel) address is configured, and something falsely filters out ICMPv6 error messages. You shouldn't worry about this case - it may be just as well that IPv4 connectivity is somehow broken.
Of course, it's debatable whether you really need to try the IPv6 addresses first - you might just as well try them second. In general, you should try addresses in the order in which they are returned from getaddrinfo. Today, systems support configuration options that let administators decide in what order addresses should be returned from getaddrinfo.
Subsequent to the question being asked the IETF has proposed an answer to this question with RFC6555, a.k.a. Happy Eyeballs.
The pertinent point being the client and server may both have IPv4 and IPv6 but a hop in between may not so it is impossible to reliably predict which path will work.
You should let the system-wide configuration decide thanks to getaddrinfo(). Just like Java does. Asking every single application to try to cater for every single possible IPv6 (mis)configuration is really not scalable! In case of a misconfiguration it is much more intuitive to the user if all or none applications break.
On the other hand you want to try to log annoying delays and time-outs profusely, so users can quickly identify what to blame. Just like every other delays ideally, including (very common) DNS time-outs.
This talk has the solution. To summarize;
Sometimes there are problems with either DNS lookups or the subsequent connection to the resolved address
You don't want to wait for connecting to an IPv6 address to timeout before connecting to the IPv4 address, or vice versa
You don't want to wait for a lookup for an AAAA record to timeout before looking for an A record or vice versa
You don't want to stall while waiting for both AAAA and A records before attempting to connect with whichever record you get back first.
The solution is to lookup AAAA and A records simultaneously and independently, and to connect independently to the resolved addresses. Use whatever connection succeeds first.
The easiest way to do this is to allow the networking API do it for you using connect-by-name networking APIs. For example, in Java:
InetSocketAddress socketAddress = new InetSocketAddress("www.example.com", 80);
SocketChannel channel = SocketChannel.open(socketAddress);
channel.write(buffer);
The slide notes say at this point:
Here we make an opaque object called an InetSocketAddress from a host
and port, and then when we open that SocketChannel, that can complete
under the covers, doing whatever is necessary, without the
application ever seeing an IP address.
Windows also has connect-by-name APIs. I don’t have code fragments for
those here.
Now, I’m not saying that all implementations of these APIs necessarily
do the right thing today, but if applications are using these APIs,
then the implementations can be improved over time.
The di!erence with getaddrinfo() and similar APIs is that they
fundamentally can’t be improved over time. The API definition is that
they return you a full list of addresses, so they have to wait until
they have that full list to give you. There’s no way getaddrinfo can
return you a partial list and then later give you some more.
Some ideas:
Allow the user to specify the preference on a per-site basis.
Try IPv4 first.
Attempt IPv6 in parallel upon the first connection.
On subsequent connections, use IPv6 if the connection was successful previously.
I say to try IPv4 first because that is the protocol which is better established and tested.