Esempio n. 1
0
void Socket::Connect() throw(SocketException) {

    if (sockfd != -1) {
        throw SocketException("can't connect already initialized socket");
    }

    Getaddrinfo();

     // loop through all the results and connect to the first we can
    for(p = servinfo; p != NULL; p = p->ai_next) {
        if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol))
            == -1) {
            //perror("client: socket");
            continue;
        }
        if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
            close(sockfd);
            //perror("client: connect");
            continue;
        }
        break;
    }
    if (p == NULL) {
        throw SocketException("failed to connect");
    }
    // store sockets addr struct
    memcpy(&addr, p->ai_addr, p->ai_addrlen);
    freeaddrinfo(servinfo);
}
Esempio n. 2
0
/* $begin open_clientfd */
int open_clientfd(char *hostname, char *port) {
    int clientfd;
    struct addrinfo hints, *listp, *p;

    /* Get a list of potential server addresses */
    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_socktype = SOCK_STREAM;  /* Open a connection */
    hints.ai_flags = AI_NUMERICSERV;  /* ... using a numeric port arg. */
    hints.ai_flags |= AI_ADDRCONFIG;  /* Recommended for connections */
    Getaddrinfo(hostname, port, &hints, &listp);
  
    /* Walk the list for one that we can successfully connect to */
    for (p = listp; p; p = p->ai_next) {
        /* Create a socket descriptor */
        if ((clientfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) 
            continue; /* Socket failed, try the next */

        /* Connect to the server */
        if (connect(clientfd, p->ai_addr, p->ai_addrlen) != -1) 
            break; /* Success */
        Close(clientfd); /* Connect failed, try another */  //line:netp:openclientfd:closefd
    } 

    /* Clean up */
    Freeaddrinfo(listp);
    if (!p) /* All connects failed */
        return -1;
    else    /* The last connect succeeded */
        return clientfd;
}
Esempio n. 3
0
/*
 * Set up threadpool and listening socket for normal listening server.
 * Set up threadpool, commandcenter, and listening socket.
 */
static int init(int portnum, struct sockaddr * sock_addr) {
	
	char strportnum[10];
	sprintf(strportnum, "%d", portnum);

	int listening_fd = -1;
	struct addrinfo * it;

	//Setup and run getaddrinfo
	struct addrinfo hints, * ai;
	memset(&hints, 0, sizeof(struct addrinfo));

	hints.ai_flags = AI_PASSIVE;
	hints.ai_socktype = SOCK_STREAM;

	Getaddrinfo(NULL, strportnum, &hints, &ai);
	
	//iterate over results of getaddrinfo and bind ipvX address
	for (it = ai; it != NULL; it = it->ai_next) {

		//check if this addrinfo has the correct family
		if (it->ai_family == AF_INET) {

			//begin listening
			sock_addr = it->ai_addr;
			listening_fd = init_listen(sock_addr);
		}
	}

	freeaddrinfo(ai);

	return listening_fd;
}
Esempio n. 4
0
struct addrinfo* getaddr( const char* server, const char* service, int fam)
{
	struct addrinfo hints;
	memset( &hints, 0, sizeof( struct addrinfo));
	hints.ai_family = fam; //AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	
	return Getaddrinfo( server, service, &hints);
}
Esempio n. 5
0
/*
 * NAME: connectory
 * USAGE: Connect to a given "host" and "port" with the given "family"
 * ARGS: family - AF_INET is the only supported argument.
 *       host - A hostname or "dotted quad" (or equivalent).
 *       port - The remote port to connect to in *HOST ORDER*.
 *
 * XXX - This so violates everything I really wanted this function to be,
 * but I changed it to call getaddrinfo() directly instead of calling
 * inet_vhostsockaddr() because I wanted it to be able to take advantage
 * of connecting to multiple protocols and multiple ip addresses (for things
 * like ``us.undernet.org'') without having to do multiple calls to
 * getaddrinfo() which could be quite costly.
 */
int	connectory (int family, const char *host, const char *port)
{
	AI	hints, *results, *ai;
	int	err;
	int	fd;
	SS	  localaddr;
	socklen_t locallen;

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = family;
	hints.ai_socktype = SOCK_STREAM;
	if ((err = Getaddrinfo(host, port, &hints, &results)))
	{
		yell("Hostname lookup for [%s:%s] failed: %s (%d)", host, port, gai_strerror(err), err);
		return -5;
	}

	fd = -1;
	for (ai = results; ai; ai = ai->ai_next) 
	{
	    /* First, look up the virtual host we use for this protocol. */
	    err = inet_vhostsockaddr(ai->ai_family, -1, &localaddr, &locallen);
	    if (err < 0)
		continue;

	    /* Now try to do the connection. */
	    fd = client_connect((SA *)&localaddr, locallen, ai->ai_addr, ai->ai_addrlen);
	    if (fd < 0)
	    {
		err = fd;
		fd = -1;
		continue;
	    }
	    else
		break;
	}

	Freeaddrinfo(results);
	if (fd < 0)
		return err;
	return fd;
}
Esempio n. 6
0
/*
 * NAME: inet_strton
 * USAGE: Convert "any" kind of address represented by a string into
 *	  a socket address suitable for connect()ing or bind()ing with.
 * ARGS: hostname - The address to convert.  It may be any of the following:
 *		IPv4 "Presentation Address"	(A.B.C.D)
 *		IPv6 "Presentation Address"	(A:B::C:D)
 *		Hostname			(foo.bar.com)
 *		32 bit host order ipv4 address	(2134546324)
 *	 storage - A pointer to a (struct sockaddr_storage) with the 
 *		"family" argument filled in (AF_INET or AF_INET6).  
 *		If "hostname" is a p-addr, then the form of the p-addr
 *		must agree with the family in 'storage'.
 */
int	inet_strton (const char *host, const char *port, SA *storage, int flags)
{
	int family = storage->sa_family;

        /* First check for legacy 32 bit integer DCC addresses */
	if ((family == AF_INET || family == AF_UNSPEC) && host && is_number(host))
	{
		((ISA *)storage)->sin_family = AF_INET;
#ifdef HAVE_SA_LEN
		((ISA *)storage)->sin_len = sizeof(ISA);
#endif
		((ISA *)storage)->sin_addr.s_addr = htonl(strtoul(host, NULL, 10));
		if (port)
			((ISA *)storage)->sin_port = htons((unsigned short)strtoul(port, NULL, 10));
		return 0;
	}
	else
	{
		AI hints;
		AI *results;
		int retval;

		memset(&hints, 0, sizeof(hints));
		hints.ai_flags = flags;
		hints.ai_family = family;
		hints.ai_socktype = SOCK_STREAM;
		hints.ai_protocol = 0;

		if ((retval = Getaddrinfo(host, port, &hints, &results))) {
		    yell("getaddrinfo(%s): %s", host, gai_strerror(retval));
		    return -5;
		}

		/* memcpy can bite me. */
		memcpy(storage, results->ai_addr, results->ai_addrlen);

		Freeaddrinfo(results);
		return 0;
	}

	return -2;
}
Esempio n. 7
0
/* $begin open_listenfd */
int open_listenfd(char *port) 
{
    struct addrinfo hints, *listp, *p;
    int listenfd, optval=1;

    /* Get a list of potential server addresses */
    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_socktype = SOCK_STREAM;             /* Accept connections */
    hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; /* ... on any IP address */
    hints.ai_flags |= AI_NUMERICSERV;            /* ... using port number */
    Getaddrinfo(NULL, port, &hints, &listp);

    /* Walk the list for one that we can bind to */
    for (p = listp; p; p = p->ai_next) {
        /* Create a socket descriptor */
        if ((listenfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) 
            continue;  /* Socket failed, try the next */

        /* Eliminates "Address already in use" error from bind */
        Setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR,    //line:netp:csapp:setsockopt
                   (const void *)&optval , sizeof(int));

        /* Bind the descriptor to the address */
        if (bind(listenfd, p->ai_addr, p->ai_addrlen) == 0)
            break; /* Success */
        Close(listenfd); /* Bind failed, try the next */
    }

    /* Clean up */
    Freeaddrinfo(listp);
    if (!p) /* No address worked */
        return -1;

    /* Make it a listening socket ready to accept connection requests */
    if (listen(listenfd, LISTENQ) < 0) {
        Close(listenfd);
	return -1;
    }
    return listenfd;
}
Esempio n. 8
0
/*
 * NAME: inet_vhostsockaddr
 * USAGE: Get the sockaddr of the current virtual host, if one is in use.
 * ARGS: family - The family whose sockaddr info is to be retrieved
 *       storage - Pointer to a sockaddr structure appropriate for family.
 *       len - This will be set to the size of the sockaddr structure that
 *             was copied, or set to 0 if no virtual host is available in
 *             the given family.
 * NOTES: If "len" is set to 0, do not attempt to bind() 'storage'!
 */
int	inet_vhostsockaddr (int family, int port, SS *storage, socklen_t *len)
{
	char	p_port[12];
	char	*p = NULL;
	AI	hints, *res;
	int	err;

	/*
	 * If port == -1, then this is a client connection, so we punt
	 * if there is no virtual host name.  But if port is NOT zero, then
	 * the caller expects us to return a sockaddr they can bind() to, 
	 * so we need to use LocalHostName, even if it's NULL.  If you 
	 * return *len == 0 for port != -1, then /dcc breaks.
	 */
	if (family == AF_UNIX || (port == -1 && !LocalHostName))
	{
		*len = 0;
		return 0;		/* No vhost needed */
	}

	/*
	 * Can it really be this simple?
	 */
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = family;
	hints.ai_socktype = SOCK_STREAM;
	if (port != -1) 
	{
		hints.ai_flags = AI_PASSIVE;
		snprintf(p_port, 12, "%u", port);
		p = p_port;
	}

	if ((err = Getaddrinfo(LocalHostName, p, &hints, &res)))
		return -10;
	memcpy(storage, res->ai_addr, res->ai_addrlen);
	*len = socklen((SA *)storage);
	return 0;
}
/* $begin open_clientfd */
int open_clientfd(char *hostname, int port)
{
    int clientfd;
    struct sockaddr_in serveraddr;
    struct addrinfo *addr_info;

    if ((clientfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        return -1;

    // use Getaddrinfo for thread safety
    if(Getaddrinfo(hostname, &addr_info) == -1){
        return -2;
    }

    bzero((char *) &serveraddr, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(port);
    serveraddr.sin_addr.s_addr = ((struct sockaddr_in*)(addr_info->ai_addr))->sin_addr.s_addr;
    freeaddrinfo(addr_info);

    if (connect(clientfd, (SA *) &serveraddr, sizeof(serveraddr)) < 0)
        return -1;
    return clientfd;
}
Esempio n. 10
0
int main (int argc, char * argv[])
{
  char opt;
  const char * optstring  = "";
  unsigned int i;
  unsigned int cnt;
  struct addrinfo hints,*res;
  struct sockaddr_in addr;
  int backlog,cs,s,on;
  struct sockaddr_in cli;

  while ((opt=getopt(argc,argv,optstring)) != -1) {
    switch(opt) {
    default : usage(argv[0]);
    }
  }

  // resolve service
  if (argv[optind] == NULL)
    usage(argv[0]);

  bzero(&hints,sizeof(hints));
  hints.ai_family = AF_INET;
  hints.ai_socktype = SOCK_STREAM;
  Getaddrinfo(NULL,argv[optind],&hints,&res);

  // process filters
  cnt = optind + 1;

  while (argv[cnt++] != NULL)
    filters_cnt++;

  filters = Malloc(filters_cnt * sizeof (char *));
  for (cnt = 0, i=optind + 1; i <= optind + filters_cnt; i++, cnt++)
    filters[cnt] = argv[i];
  
  // prepare address
  addr.sin_family = AF_INET;
  addr.sin_port = ((struct sockaddr_in *)(res->ai_addr))->sin_port;
  addr.sin_addr.s_addr = INADDR_ANY;
  bzero(&addr.sin_zero,sizeof(addr.sin_zero)); 
  
  // free getaddrinfo stuff
  freeaddrinfo(res);

  // socket
  s = Socket(PF_INET, SOCK_STREAM, 0x0);

  // enable address reuse ( not TCP wait crap )
  on = 1;
  Setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

  // bind 
  Bind(s,(struct sockaddr *)&addr,sizeof(addr));

  // listen
  socklen_t clilen = sizeof(cli);
  backlog = 10;
  Listen(s,backlog);

  for ( ; ; ) {
    cs = Accept(s,&cli,&clilen);

#ifdef PREFORK
    if ( Fork() ) {
      printf ("%s: ",inet_ntoa(cli.sin_addr));
    } else {
      process(cs,&cli);
      return 0;
    }
#else
    struct args_p *arg = (struct args_p*)malloc(sizeof(struct args_p));
    arg->cs = cs;
    arg->cli = &cli;
    pthread_create(&arg->tid, NULL, &process_p, arg);
    pthread_detach(arg->tid);
#endif

  }
  
  /* NOTREACHED */
  Close (s);
  return 0;
}
Esempio n. 11
0
int main(int argc, char* argv[]) {

	struct	sockaddr_in sad; // structure to hold an IP address	

	struct addrinfo hint;
	struct addrinfo *serverptr;

	int	sd;		     // socket descriptor			
	int	port;		     // protocol port number		
	char	*host;		     // pointer to host name		
	char	buf[BUFSIZE];	     // buffer for data from the server
	char buf2[BUFSIZE];
	int   bytes_read;          // number of bytes read from socket
	int   bytes_expected;

	memset((char *)&sad,0,sizeof(sad)); // clear sockaddr structure	
	sad.sin_family = AF_INET;	      // set family to Internet	

	// Check command-line arguments
	int i; 
	for(i = 0; i < BUFSIZE; i++) {
		buf2[i] = 'A';
	}
	buf2[i-1] = 0;

	if (argc < 3) {
		printf("usage: getfile [ host ] [ port ]\n");
		exit(-1);
	}

	host = argv[1];		
	port = atoi(argv[2]);	

	if (port <= 0) {	
		// test for legal value		
		// print error message and exit	
		fprintf(stderr,"SOURCE: bad port number %s\n",argv[2]);
		exit(1);
	}

	//  prepare the hint information
	bzero(&hint, sizeof(hint));
	hint.ai_flags = AI_CANONNAME;
	hint.ai_family = AF_INET;

	Getaddrinfo(host, NULL, &hint, &serverptr);

	bcopy(serverptr->ai_addr, (char *)&sad, serverptr->ai_addrlen);

	sad.sin_port = htons((u_short)port);

	// Create a socket. 
	sd = Socket(AF_INET, SOCK_STREAM, 0);

	// Connect the socket to the specified server. 

	Connect(sd, (struct sockaddr *)(&sad), sizeof(struct sockaddr));

	// Repeatedly read data from socket and write to user's screen. 

	strcpy(buf, "here is a message for you");
	bytes_expected = strlen(buf) + 1;

	printf("SOURCE: Sending 'here is a message for you' \n");

	Writen(sd, &bytes_expected, sizeof(int));
	Writen(sd, buf, bytes_expected);

	bytes_expected = strlen(buf2) + 1;

	printf("SOURCE: Sending %d byte msg\n", bytes_expected);
	printf("SOURCE: Sending '%s' byte msg\n", buf2);

	Writen(sd, &bytes_expected, sizeof(int));
	Writen(sd, buf2, bytes_expected);

	bytes_read = Readn(sd, buf, sizeof(int));
	printf("SOURCE: Expecting %d bytes from sink\n", bytes_read);

	i = Readn(sd,buf,bytes_read);
	printf("SOURCE: Got %d bytes from sink\n",i);
	buf[i+1] = 0;
	printf("SOURCE: Got '%s' from sink\n",buf);

	// Close the socket. 
	Close(sd);

	// Terminate the client program gracefully. 
	exit(0);
}
Esempio n. 12
0
/* the ultimate(?) socat resolver function
 node: the address to be resolved; supported forms:
   1.2.3.4 (IPv4 address)
   [::2]   (IPv6 address)
   hostname (hostname resolving to IPv4 or IPv6 address)
   hostname.domain (fq hostname resolving to IPv4 or IPv6 address)
 service: the port specification; may be numeric or symbolic
 family: PF_INET, PF_INET6, or PF_UNSPEC permitting both
 socktype: SOCK_STREAM, SOCK_DGRAM
 protocol: IPPROTO_UDP, IPPROTO_TCP
 sau: an uninitialized storage for the resulting socket address
 returns: STAT_OK, STAT_RETRYLATER
*/
int xiogetaddrinfo(const char *node, const char *service,
		   int family, int socktype, int protocol,
		   union sockaddr_union *sau, socklen_t *socklen,
		   unsigned long res_opts0, unsigned long res_opts1) {
   int port = -1;	/* port number in network byte order */
   char *numnode = NULL;
   size_t nodelen;
   unsigned long save_res_opts = 0;
#if HAVE_GETADDRINFO
   struct addrinfo hints = {0};
   struct addrinfo *res = NULL;
#else /* HAVE_GETIPNODEBYNAME || nothing */
   struct hostent *host;
#endif
   int error_num;

#if HAVE_RESOLV_H
   if (res_opts0 | res_opts1) {
      if (!(_res.options & RES_INIT)) {
         Res_init();	/*!!! returns -1 on error */
      }
      save_res_opts = _res.options;
      _res.options &= ~res_opts0;
      _res.options |= res_opts1;
      Debug2("changed _res.options from 0x%lx to 0x%lx",
	     save_res_opts, _res.options);
   }
#endif /* HAVE_RESOLV_H */
   memset(sau, 0, *socklen);
   sau->soa.sa_family = family;

   /* if service is numeric we don't want to have a lookup (might take long
      with NIS), so we handle this specially */
   if (service && isdigit(service[0]&0xff)) {
      char *extra;
      port = htons(strtoul(service, &extra, 0));
      if (*extra != '\0') {
	 Warn2("xiogetaddrinfo(, \"%s\", ...): extra trailing data \"%s\"",
	       service, extra);
      }
      service = NULL; 
   }

   /* the resolver functions might handle numeric forms of node names by
      reverse lookup, that's not what we want.
      So we detect these and handle them specially */
   if (node && isdigit(node[0]&0xff)) {
#if HAVE_GETADDRINFO
      hints.ai_flags |= AI_NUMERICHOST;
#endif /* HAVE_GETADDRINFO */
      if (family == PF_UNSPEC) {
	 family = PF_INET;
#if HAVE_GETADDRINFO
      } else if (family == PF_INET6) {
	 /* map "explicitely" into IPv6 address space; getipnodebyname() does
	    this with AI_V4MAPPED, but not getaddrinfo() */
	 if ((numnode = Malloc(strlen(node)+7+1)) == NULL) {
#if HAVE_RESOLV_H
	    if (res_opts0 | res_opts1) {
	       _res.options = (_res.options & (~res_opts0&~res_opts1) |
			       save_res_opts& ( res_opts0| res_opts1));
	    }
#endif
	    return STAT_NORETRY;
	 }
	 sprintf(numnode, "::ffff:%s", node);
	 node = numnode;
	 hints.ai_flags |= AI_NUMERICHOST;
#endif /* HAVE_GETADDRINFO */
      }
#if WITH_IP6
   } else if (node && node[0] == '[' && node[(nodelen=strlen(node))-1]==']') {
      if ((numnode = Malloc(nodelen-1)) == NULL) {
#if HAVE_RESOLV_H
	 if (res_opts0 | res_opts1) {
	    _res.options = (_res.options & (~res_opts0&~res_opts1) |
			    save_res_opts& ( res_opts0| res_opts1));
	 }
#endif
	 return STAT_NORETRY;
      }
      strncpy(numnode, node+1, nodelen-2);
      numnode[nodelen-2] = '\0';
      node = numnode;
#if HAVE_GETADDRINFO
      hints.ai_flags |= AI_NUMERICHOST;
#endif /* HAVE_GETADDRINFO */
      if (family == PF_UNSPEC)  family = PF_INET6;
#endif /* WITH_IP6 */
   }

#if HAVE_GETADDRINFO
   if (node != NULL || service != NULL) {
      struct addrinfo *record;

      if (socktype != SOCK_STREAM && socktype != SOCK_DGRAM) {
	 /* actual socket type value is not supported - fallback to a good one */
	 socktype = SOCK_DGRAM;
      }
      if (protocol != IPPROTO_TCP && protocol != IPPROTO_UDP) {
	 /* actual protocol value is not supported - fallback to a good one */
	 if (socktype == SOCK_DGRAM) {
	    protocol = IPPROTO_UDP;
	 } else {
	    protocol = IPPROTO_TCP;
	 }
      }
      hints.ai_flags |= AI_PASSIVE;
      hints.ai_family = family;
      hints.ai_socktype = socktype;
      hints.ai_protocol = protocol;
      hints.ai_addrlen = 0;
      hints.ai_addr = NULL;
      hints.ai_canonname = NULL;
      hints.ai_next = NULL;

      if ((error_num = Getaddrinfo(node, service, &hints, &res)) != 0) {
	 Error7("getaddrinfo(\"%s\", \"%s\", {%d,%d,%d,%d}, {}): %s",
		node, service, hints.ai_flags, hints.ai_family,
		hints.ai_socktype, hints.ai_protocol,
		(error_num == EAI_SYSTEM)?
		strerror(errno):gai_strerror(error_num));
	 if (res != NULL)  freeaddrinfo(res);
	 if (numnode)  free(numnode);

#if HAVE_RESOLV_H
	 if (res_opts0 | res_opts1) {
	    _res.options = (_res.options & (~res_opts0&~res_opts1) |
			    save_res_opts& ( res_opts0| res_opts1));
	 }
#endif
	 return STAT_RETRYLATER;
      }
      service = NULL;	/* do not resolve later again */

      record = res;
      if (family == PF_UNSPEC && xioopts.preferred_ip == '0') {
	 /* we just take the first result */
	 family = res[0].ai_addr->sa_family;
      }
      if (family == PF_UNSPEC) {
	 int trypf;
	 trypf = (xioopts.preferred_ip=='6'?PF_INET6:PF_INET);
	 /* we must look for a matching entry */
	 while (record != NULL) {
	    if (record->ai_family == trypf) {
	       family = trypf;
	       break;	/* family and record set accordingly */
	    }
	    record = record->ai_next;
	 }
	 if (record == NULL) {
	    /* we did not find a "preferred" entry, take the first */
	    record = res;
	    family = res[0].ai_addr->sa_family;
	 }
      }

      switch (family) {
#if WITH_IP4
      case PF_INET:
	 if (*socklen > record->ai_addrlen) {
	    *socklen = record->ai_addrlen;
	 }
	 memcpy(&sau->ip4, record->ai_addr, *socklen);
	 break;
#endif /* WITH_IP4 */
#if WITH_IP6
      case PF_INET6:
#if _AIX
	 /* older AIX versions pass wrong length, so we correct it */
	 record->ai_addr->sa_len = sizeof(struct sockaddr_in6);
#endif
	 if (*socklen > record->ai_addrlen) {
	    *socklen = record->ai_addrlen;
	 }
	 memcpy(&sau->ip6, record->ai_addr, *socklen);
	 break;
#endif /* WITH_IP6 */
      default:
	 Error1("address resolved to unknown protocol family %d",
		record->ai_addr->sa_family);
	 break;
      }
      freeaddrinfo(res);
   } else {
      switch (family) {
#if WITH_IP4
      case PF_INET:  *socklen = sizeof(sau->ip4); break;
#endif /* WITH_IP4 */
#if WITH_IP6
      case PF_INET6: *socklen = sizeof(sau->ip6); break;
#endif /* WITH_IP6 */
      }
   }

#elif HAVE_GETIPNODEBYNAME /* !HAVE_GETADDRINFO */

   if (node != NULL) {
      /* first fallback is getipnodebyname() */
      if (family == PF_UNSPEC) {
#if WITH_IP4 && WITH_IP6
	 family = xioopts.default_ip=='6'?PF_INET6:PF_INET;
#elif WITH_IP6
	 family = PF_INET6;
#else
	 family = PF_INET;
#endif
      }
      host = Getipnodebyname(node, family, AI_V4MAPPED, &error_num);
      if (host == NULL) {
	 const static char ai_host_not_found[] = "Host not found";
	 const static char ai_no_address[]     = "No address";
	 const static char ai_no_recovery[]    = "No recovery";
	 const static char ai_try_again[]      = "Try again";
	 const char *error_msg = "Unknown error";
	 switch (error_num) {
	 case HOST_NOT_FOUND: error_msg = ai_host_not_found; break;
	 case NO_ADDRESS:     error_msg = ai_no_address;
	 case NO_RECOVERY:    error_msg = ai_no_recovery;
	 case TRY_AGAIN:      error_msg = ai_try_again;
	 }
	 Error2("getipnodebyname(\"%s\", ...): %s", node, error_msg);
      } else {
	 switch (family) {
#if WITH_IP4
	 case PF_INET:
	    *socklen = sizeof(sau->ip4);
	    sau->soa.sa_family = PF_INET;
	    memcpy(&sau->ip4.sin_addr, host->h_addr_list[0], 4);
	    break;
#endif
#if WITH_IP6
	 case PF_INET6:
	    *socklen = sizeof(sau->ip6);
	    sau->soa.sa_family = PF_INET6;
	    memcpy(&sau->ip6.sin6_addr, host->h_addr_list[0], 16);
	    break;
#endif
	 }
      }
      freehostent(host);
   }

#else /* !HAVE_GETIPNODEBYNAME */

   if (node != NULL) {
      /* this is not a typical IP6 resolver function - but Linux
	 "man gethostbyname" says that the only supported address type with
	 this function is AF_INET _at present_, so maybe this fallback will
	 be useful somewhere sometimesin a future even for IP6 */
      if (family == PF_UNSPEC) {
#if WITH_IP4 && WITH_IP6
	 family = xioopts.default_ip=='6'?PF_INET6:PF_INET;
#elif WITH_IP6
	 family = PF_INET6;
#else
	 family = PF_INET;
#endif
      }
      /*!!! try gethostbyname2 for IP6 */
      if ((host = Gethostbyname(node)) == NULL) {
	 Error2("gethostbyname(\"%s\"): %s", node,
		h_errno == NETDB_INTERNAL ? strerror(errno) :
		hstrerror(h_errno));
#if HAVE_RESOLV_H
	 if (res_opts0 | res_opts1) {
	    _res.options = (_res.options & (~res_opts0&~res_opts1) |
			    save_res_opts& ( res_opts0| res_opts1));
	 }
#endif
	 return STAT_RETRYLATER;
      }
      if (host->h_addrtype != family) {
	 Error2("xioaddrinfo(): \"%s\" does not resolve to %s",
		node, family==PF_INET?"IP4":"IP6");
      } else {
	 switch (family) {
#if WITH_IP4
	 case PF_INET:
	    *socklen = sizeof(sau->ip4);
	    sau->soa.sa_family = PF_INET;
	    memcpy(&sau->ip4.sin_addr, host->h_addr_list[0], 4);
	    break;
#endif /* WITH_IP4 */
#if WITH_IP6
	 case PF_INET6:
	    *socklen = sizeof(sau->ip6);
	    sau->soa.sa_family = PF_INET6;
	    memcpy(&sau->ip6.sin6_addr, host->h_addr_list[0], 16);
	    break;
#endif /* WITH_IP6 */
	 }
      }
   }

#endif

#if WITH_TCP || WITH_UDP
   if (service) {
      port = parseport(service, protocol);
   }
   if (port >= 0) {
      switch (family) {
#if WITH_IP4
      case PF_INET:  sau->ip4.sin_port  = port; break;
#endif /* WITH_IP4 */
#if WITH_IP6
      case PF_INET6: sau->ip6.sin6_port = port; break;
#endif /* WITH_IP6 */
      }
   }      
#endif /* WITH_TCP || WITH_UDP */

   if (numnode)  free(numnode);

#if HAVE_RESOLV_H
   if (res_opts0 | res_opts1) {
      _res.options = (_res.options & (~res_opts0&~res_opts1) |
		      save_res_opts& ( res_opts0| res_opts1));
   }
#endif /* HAVE_RESOLV_H */
   return STAT_OK;
}
Esempio n. 13
0
int main(int argc, char* argv[]) {

    struct sockaddr_in sad; // structure to hold an IP address
    struct sockaddr_in cad; // structure to hold an IP address

    struct addrinfo hint;
    struct addrinfo *serverptr;

    int	sd, sd2;		     // socket descriptor
    int	port;		     // protocol port number
    char	*host;		     // pointer to host name
    char	buf[BUFSIZE];	     // buffer for data from the server
    char buf2[BUFSIZE];
    int   bytes_expected;

    int alen;

    memset((char *)&sad,0,sizeof(sad)); // clear sockaddr structure
    sad.sin_family = AF_INET;	      // set family to Internet

    int i;
    for(i = 65; i < BUFSIZE + 65; i++)
        buf2[i-65] = i % 256;

    if (argc < 3) {
        printf("usage: %s [ host ] [ port ]\n",argv[0]);
        exit(-1);
    }

    host = argv[1];
    port = atoi(argv[2]);

    if (port <= 0) {
        fprintf(stderr,"SOURCE: bad port number %s\n",argv[2]);
        exit(1);
    }

    //  prepare the hint information
    bzero(&hint, sizeof(hint));
    hint.ai_flags = AI_CANONNAME;
    hint.ai_family = AF_INET;

    Getaddrinfo(host, NULL, &hint, &serverptr);

    bcopy(serverptr->ai_addr, (char *)&sad, serverptr->ai_addrlen);

    sad.sin_port = htons((u_short)port);

    // Create a socket.
    sd = Socket(AF_INET, SOCK_STREAM, 0);

    //Bind the socket to the specififed port
    Bind(sd, (struct sockaddr *) &sad, sizeof(sad));

    printf("SINK: Socket created\n");

    listen(sd, 5);
    alen = sizeof(cad);

    printf("SINK: Waiting for a connection\n");

    sd2 = accept(sd, (struct sockaddr *) &cad, &alen);

    printf("SINK: Waiting to receive a message\n");

    Readn(sd2, &bytes_expected, sizeof(int));
    Readn(sd2, buf2, bytes_expected+1);

    printf("SINK: Received a message\n");
    printf("SINK: (%d) '%s'\n", bytes_expected, buf2);

    Readn(sd2, &bytes_expected, sizeof(int));
    Readn(sd2, buf2, bytes_expected+1);

    printf("SINK: Received a message\n");
    printf("SINK: (%d) '%s'\n", bytes_expected, buf2);

    printf("SINK: Responding to Source\n");

    strcpy(buf, "message recieved");
    bytes_expected = strlen(buf);

    Writen(sd, &bytes_expected, sizeof(int));
    Writen(sd, buf, bytes_expected);

    close(sd2);
    close(sd);
    return 1;
}
Esempio n. 14
0
int main(int argc, char* argv[]) {

	if (argc < 6) {
		fprintf(stderr, "usage: %s [ msgbytes ] [ host ] [ port ] [ protocol ] [ numTrials ]\n",argv[0]);
		exit(-1);
	}

	int msgbytes = atoi(argv[1]);
	char *host = argv[2];
	int port = atoi(argv[3]);		     // protocol port number		
	char *prot = argv[4];
	int numTrials = atoi(argv[5]);

	if (port <= 0) {	
		fprintf(stderr,"PINGPONG: bad port number %s\n",argv[3]);
		exit(1);
	}

	if(msgbytes < 1 || msgbytes > 65000) {
		fprintf(stderr,"PINGPONG: bad msgbytes size (%d), 0 < msgbytes < 65001\n", msgbytes);
		exit(1);
	}

	if(numTrials < 0 || numTrials > 1000000) {
		fprintf(stderr, "PINGPONG: bad numTrials (%d) , 0 < numTrials < 1001\n", numTrials);
		exit(1);
	}
	
	struct addrinfo *serverptr;
	struct addrinfo hint;

	//  prepare the hint information
	bzero(&hint, sizeof(hint));
	hint.ai_flags = AI_CANONNAME;
	hint.ai_family = AF_INET;

	Getaddrinfo(host, NULL, &hint, &serverptr);
	
	struct timeval start, end;

	double times [numTrials];
	int i;

	if(strncmp(prot,"UDP", 3) == 0 ) {

		for(i = 0; i < numTrials; i++) {
			gettimeofday(&start, NULL);

			struct sockaddr_in cad; // structure to hold an IP address	

			struct sockaddr_in sad; // structure to hold an ip address	
			memset((char *)&sad,0,sizeof(sad)); // clear sockaddr structure	
			sad.sin_family = AF_INET;	      // set family to internet	
			bcopy(serverptr->ai_addr, (char *) &sad,  serverptr->ai_addrlen);
			sad.sin_port = htons((u_short)port);

			struct sockaddr_in sad2; // structure to hold an ip address	
			memset((char *)&sad2,0,sizeof(sad2)); // clear sockaddr structure	
			sad2.sin_family = AF_INET;	      // set family to internet	
			sad2.sin_addr.s_addr = htonl(INADDR_ANY);
			sad2.sin_port = htons((u_short)port+1);

//			printsin(&sad, "PRINT"," SIN:");
			
			fflush(stdout);
			
			int fsize = sizeof(struct sockaddr);
			int bytes_expected, sd;
			sd = Socket(AF_INET, SOCK_DGRAM, 0);

			Bind(sd, (struct sockaddr *) &sad2, sizeof(sad2));
			int *msg = malloc(msgbytes);
			int *dump = malloc(msgbytes);

//	fprintf(stderr,"PINGPONG: UDP Socket created\n");
//	fprintf(stderr,"PINGPONG: Sending a (%d) sized datagram\n", msgbytes);	

			Sendto(sd, &msgbytes, sizeof(msgbytes), 0,(struct sockaddr *) &sad, sizeof(sad));
			Sendto(sd, msg, sizeof(msg), 0, (struct sockaddr *) &sad, sizeof(sad));

//	fprintf(stderr,"PINGPONG: Datagram sent\n");
//	fprintf(stderr,"PINGPONG: Awaiting the response\n");

			Recvfrom(sd, &bytes_expected, sizeof(bytes_expected),0,(struct sockaddr *)  &cad, (socklen_t *) &fsize);
			Recvfrom(sd, dump, sizeof(dump),0,(struct sockaddr *) &cad, (socklen_t *) &fsize);

			gettimeofday(&end, NULL);			
			times[i] = elapsed(end,start);

//	fprintf(stderr,"PINGPONG: UDP received a %d size packet\n", bytes_expected);
			close(sd);
		}
//		fprintf(stderr,"PINGPONG: Execution done terminating\n");

	} else if(strncmp(prot,"TCP", 3) == 0) {
		char	buf[msgbytes];	     // buffer for data from the server
		for(i = 0; i < msgbytes; i++)
			buf[i] = 'A';
		buf[msgbytes-1] = 0;


		for(i = 0; i < numTrials; i++) {
			gettimeofday(&start, NULL);
			struct sockaddr_in sad; // structure to hold an IP address	
			memset((char *)&sad,0,sizeof(sad)); // clear sockaddr structure	
			sad.sin_family = AF_INET;	      // set family to Internet	
			bcopy(serverptr->ai_addr, (char *) &sad, serverptr->ai_addrlen);
			sad.sin_port = htons((u_short)port);

			int	sd;		   			
			sd = Socket(AF_INET, SOCK_STREAM, 0);

//			fprintf(stderr,"PINGPONG: Connecting to reflector TCP\n");

			Connect(sd, (struct sockaddr *) (&sad), sizeof(struct sockaddr));

//			fprintf(stderr,"PINGPONG: TCP connection established\n");

//			fprintf(stderr,"PINGPONG: Sending a message\n");
//			fprintf(stderr,"PINGPONG: Sending a message (%d) '%s'\n", msgbytes, buf);

			Writen(sd, &msgbytes, sizeof(int));
			Writen(sd, buf, msgbytes);

//			fprintf(stderr,"PINGPONG: Awating respone\n");

			Readn(sd, &msgbytes, sizeof(int));
			Readn(sd, buf, msgbytes);

//			fprintf(stderr,"PINGPONG: Recieved message (%d) '%s'\n", msgbytes, buf);
//			fprintf(stderr,"PINGPONG: Received response terminated\n");

			gettimeofday(&end, NULL);			
			times[i] = elapsed(end,start);


			close(sd);		
		}
	} else {
//		fprintf(stderr,"Improper protocol %s expecting either 'TCP' or 'UDP'\n", argv[2]);
	}


	double average = 0;

	for(i = 0; i < numTrials; i++)
		average += times[i];
	average /= numTrials;

	double stdDev = 0;

	for(i = 0; i < numTrials; i++)
		stdDev += (times[i] - average) * (times[i] - average);

	stdDev /= numTrials;
	stdDev = sqrt(stdDev);

	double error = 1.96 * (stdDev / sqrt(numTrials-1));

//	fprintf(stderr,"PINGPONG: Average of %d trials is %f\n", numTrials, average);
//	fprintf(stderr,"PINGPONG: Standard Deviation is %f\n", stdDev);
//	fprintf(stderr,"PINGPONG: Error is %f\n", error);

	printf("%d %f %f\n", msgbytes, average, error);

	return 1;
}