CONNECTBYNAME(3)                                              CONNECTBYNAME(3)



NAME
       connectbyname - initiate an IP version agnostic connection

SYNOPSIS
       #include <easyv6.h>

       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 <easyv6.h>
       #include <stdio.h>
       #include <errno.h>
       #include <stdlib.h> /* exit */
       #include <unistd.h> /* fcntl */
       #include <fcntl.h> /* fcntl */
       #include <string.h> /* memset */
       #include <sys/socket.h>

       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 <bill@herrin.us>.



                                March 18, 2012                CONNECTBYNAME(3)
