4

I have a c-program that needs to connect to a server and send a tcp payload and wait for the response. This works well for normal use but since I have two different network interfaces, let us call them if0 and if1 on the computer running the program, sometimes one of the network interfaces are not able to forward the traffic. This is a fact that I cannot change unfortunately.

To handle this gracefully since the OS cannot help me route the data to the correct interface, I send the payload using both if0 and if1. I create a socket and I use bind to bind the socket to a specific interface and I do that for both if0 and if1.

Unfortunately this did not work as I planned because gethostbyname that I use to resolve the host name used only one interface of course. Unfortunately I am not able to make changes to the OS config at this particular problem, I need to bypass any logic in the OS and make sure traffic goes to a specific interface.

I have the following code for address lookup:

struct hostent *remoteHostEnt = gethostbyname(hostName);

Is there any way that I can make gethostbyname using a specific interface as well? I would like to try using gethostbyname using both if0 and if1 and use any acceptable result.

Do I need to make my own DNS lookup implementation and use a socket for this or is there something in posix c I can use? Or maybe there is a library I can use?

www.jensolsson.se
  • 3,023
  • 2
  • 35
  • 65
  • `gethostbyname()` is obsolete. User `getaddrinfo()` (http://man7.org/linux/man-pages/man3/getaddrinfo.3.html) instead. – alk May 03 '15 at 10:57
  • "*the OS cannot help me route the data to the correct interface*" why not? – alk May 03 '15 at 10:59
  • Both interfaces are mapped to the same FQDN? – alk May 03 '15 at 11:01
  • Also: You let the TCP/IP client program call `bind()`? Why? Because on the client-machine there is no routing table around, or what? – alk May 03 '15 at 11:05
  • Thanks for the reply @alk Unfortunately I have no control over the OS configuration. It has routing tables but unfortunately sometimes they are messed up or it takes too long time for them to update if an interface suddenly stops sending traffic thru. Will look into getaddrinfo() – www.jensolsson.se May 03 '15 at 12:33
  • Does this mean I can use the first parameter, node, to set the interface? http://stackoverflow.com/questions/7492269/choosing-the-interface-in-multi-homed-hosts – www.jensolsson.se May 03 '15 at 12:39
  • If you are after the local interfaces you might like to have a look at `getifaddrs()`. – alk May 03 '15 at 13:15
  • I am already using getifaddrs. I know the ip addresses and the name of all the interfaces. The problem is in step two to make sure getaddrinfo() to use the particular interface. – www.jensolsson.se May 03 '15 at 14:12
  • I think until now I **fully** misunderstood the question. Is "the real" question that the DNS request that might be issued by `gethostbyname()` fails? – alk May 03 '15 at 14:15
  • @alk exactly so, sorry if my question was not clear enough – www.jensolsson.se May 03 '15 at 14:16
  • Pheww, using IP on a host with broken routing tables ... - not nice. I need to think about this. – alk May 03 '15 at 14:20
  • There is the "resolver"-interface (`man 3 resolver`), but this covers away the underlying stuff. So I'd say you won't get around doing the DNS query yourself. Or, if you have root rights just fix the routing tables ... - but I suspect you don't have ... ;-) – alk May 03 '15 at 14:28
  • Why are you also trying to use DNS on a system that is clearly borked? If you're trying to implement some sort of watchdog or failover notification service then resolve the names while everything is working, or even resolve the names at configuration time. Better yet use a lower-layer failover sub-system so that applications don't even have to know that there are multiple interfaces. I.e. fix the right problem with the right tools! :-) – Greg A. Woods May 08 '15 at 16:40
  • @GregA.Woods Unfortunately I cannot be sure that the IP addresses the DNS names point to remain the same after configuration so that is not an option. – www.jensolsson.se May 08 '15 at 16:42
  • Then resolve them _when everything is working_ and do not try to resolve DNS after everything is broken. You really need to describe this scenario more completely and describe the real purpose and requirements for your program. I don't expect you'll get any good answers to a mysterious question with vague and impossible-sounding limitations. What are you _really_ trying to do? – Greg A. Woods May 08 '15 at 16:46

2 Answers2

3

You can make DNS queries with a specific network interface using c-ares (as shown in c-ares specifying network interface for the DNS resolves).

There is a c-ares example at How do I resolve an IP into host using c-ares?.

Community
  • 1
  • 1
0

If you cannot change the system configuration, you're pretty much condemned to implementing your own DNS resolver within your application. You could base your code on ADNS, or on the DNS resolver included in Polipo

jch
  • 5,382
  • 22
  • 41
  • I looked into the projects suggested. The Polipo DNS resolver was interesting. I actually ended up taking some inspiration from it and wrote a small pice of code to make the basic DNS request I need by hand. It was just about 30 lines of code in the end and it works perfectly. Since I have control over the DNS records of the target this solution will most likely be enough. Have done a lot of testing and it is a huge improvement in reliability – www.jensolsson.se May 08 '15 at 16:54