CONNECTBYNAME(3) CONNECTBYNAME(3) NAME connectbyname - initiate an IP version agnostic connection SYNOPSIS #include int connectbyname(const char *name, const char *service, long long timeout, struct CONNECTOPTIONS *options); DESCRIPTION The connectbyname() function creates a SOCK_STREAM socket (a TCP socket) and connects to host name on port service via IPv4, IPv6 or any other eligible Internet protocol. connectbyname() parallelizes its work, attempting connections to multiple IP addresses associated with the name if the first does not immediately respond. It waits for any of the attempted connections to complete and returns the first one which does. connectbyname() will abort if it can not establish a connection within timeout milliseconds give or take a second. The wait before trying the next address scales based on the timeout but is not more than 1 second and not not less than 100ms. Setting the time outto less than 5 seconds (5000 ms) is not recommended. Note that if the system timeout for connect()s is shorter than the timeout passed to this function, the shorter timeout will be used. If options is not NULL, connectbyname() will use the following struc- ture to fine tune its behavior: struct CONNECTOPTIONS { const struct addrinfo *like; int dnspinning; const struct addrinfo *skip; struct addrinfo *picked; char reportpicked; struct CONNECTBYNAMEDETAILS *details; char reportdetails; int getaddrinfoerror; int numaddresses; }; like connectbyname() will prefer to connect to the addresses in this addrinfo structure if any are associated with the name. Use this to encourage connectbyname() to use the same destination on con- nections subsequent to the first. dnspinning If the underlying protocol accepts connections to an address which doesn't consider itself to have the provided name, con- nectbyname will refuse to connect to any address not present in the like list. TCP, for example, only cares about the numeric address during the connect() phase. This supports Web Browser DNS pinning which is used to resolve the DNS rebinding Javascript security vulnerability. Use of this option is STRONGLY DISCOURAGED. skip Do not connect to these addresses even if they are associated with the name. Skipped addresses will not be used even if they are liked. Suppose you connectbyname() to an email server. You get a con- nection but the server never sends an SMTP banner. There are other addresses for the server. What do you do? connectbyname() again but exclude the address which didn't return a banner by including it in the skip list. reportpicked If reportpicked is set to a non-zero value then on success, con- nectbyname() sets picked to the addrinfo structure associated with the connection. May be used in later calls assigned to like or skip. Must be freed by the caller with freeaddrinfo(3). reportdetails Regardless of success or failure, fill in details with the remote addresses tried and the errno for each. getaddrinfoerror If the name lookup fails, report an error consistent with getad- drinfo(3). numaddresses Fill in with the number of candidate adddresses that connectby- name() tried (on failure) or could have tried (on success). If reportdetails is set to a non-zero value then details is filled in with the following structure: struct CONNECTBYNAMEDETAILS { const struct addrinfo *addresslist; struct CONNECTBYNAMERESULT results[]; }; struct CONNECTBYNAMERESULT { const struct addrinfo *address; int error; }; There are exactly numaddresses results. The first (and only the first) addrinfo struct in each result contains the address associated with the errno from connect() in error. Free *details with: freeaddrinfo(details->addresslist); free(details); RETURN VALUE On success, a file descriptor for the new connected socket is returned. On error, -1 is returned, and errno is set appropriately. Note that the returned socket will be in non-blocking mode. If blocking mode is desired, use fcntl(). ERRORS Errno will be set to the numerically highest errno set by any of the underlying calls to connect(2), or: EFAULT The attempt to find an address for the name or service failed or timed out. EXAMPLE #include #include #include #include /* exit */ #include /* fcntl */ #include /* fcntl */ #include /* memset */ #include void drainsocket (int socket) { int fcntlflags, count; char bytes[100]; fcntlflags = fcntl(socket,F_GETFL,0); fcntl(socket,F_SETFL,fcntlflags & (~O_NONBLOCK)); shutdown (socket,SHUT_WR); while ((count=read(socket,bytes,100))>0) { fwrite (bytes,count,1,stdout); } shutdown (socket,SHUT_RD); close (socket); return; } int main (int argc, char **argv) { int socket; char *host, *service; struct CONNECTOPTIONS options; char s[200], *address, *p; host="addrtest.dirtside.com"; service="ssh"; if (argc>1) host=argv[1]; if (argc>2) service=argv[2]; memset (&options,0,sizeof(options)); options.reportpicked = 1; socket = connectbyname (host,service,10000,&options); address = addrinfototext(options.picked,s,200); if (address) printf ("Connected to IP Address: %s0,address); if (options.picked) { freeaddrinfo(options.picked); options.picked=NULL; } if (socket<0) { printf ("Connectbyname failed: socket=%d, errno=%d, error=%s0, socket,errno,strerror(errno)); } else drainsocket(socket); return 0; } SEE ALSO addrinfototext(3), connectbyaddrinfo(3), getpeernametext(3), listenbyname(3), timeoutgetaddrinfo(3), AUTHOR libeasyv6 was written by William Herrin . March 18, 2012 CONNECTBYNAME(3)