예제 #1
0
int udp_connect(char *addr, int port, struct sockaddr_in *serv)
{
	struct sockaddr_in sv;
	int sock, optval = 1;

	if (serv == NULL)
		serv = &sv;
	if (!fill_sockaddr(serv, addr, port))
		return -1;
	sock = socket(AF_INET, SOCK_DGRAM, 0);
	if (sock < 0)
	{
		LOGL(0, "udp_connect failed: socket() %s", strerror(errno));
		return -1;
	}

	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0)
	{
		LOGL(0, "udp_bind: setsockopt(SO_REUSEADDR): %s", strerror(errno));
		return -1;
	}

	if (connect(sock, (struct sockaddr *) serv, sizeof(*serv)) < 0)
	{
		LOGL(0, "udp_connect: failed: bind(): %s", strerror(errno));
		return -1;
	}
	LOG("New UDP socket %d connected to %s:%d", sock, inet_ntoa(serv->sin_addr),
			ntohs(serv->sin_port));
	return sock;
}
예제 #2
0
int tcp_listen(char *addr, int port)
{
	struct sockaddr_in serv;
	int sock, optval = 1;

	if (!fill_sockaddr(&serv, addr, port))
		return -1;

	sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock < 0)
	{
		LOGL(0, "tcp_listen failed: socket(): %s", strerror(errno));
		return -1;
	}
	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0)
	{
		LOGL(0, "tcp_listen failed: setsockopt(SO_REUSEADDR): %s",
				strerror(errno));
		return -1;
	}

	if (bind(sock, (struct sockaddr *) &serv, sizeof(serv)) < 0)
	{
		LOGL(0, "tcp_listen: failed: bind() on address: %s, port %d : error %s",
				addr ? addr : "ANY", port, strerror(errno));
		return -1;
	}
	if (listen(sock, 10) < 0)
	{
		LOGL(0, "tcp_listen: listen(): %s", strerror(errno));
		return -1;
	}
	return sock;
}
예제 #3
0
int udp_bind(char *addr, int port)
{
	struct sockaddr_in serv;
	int sock, optval = 1;

	if (!fill_sockaddr(&serv, addr, port))
		return -1;
	sock = socket(AF_INET, SOCK_DGRAM, 0);
	if (sock < 0)
	{
		LOGL(0, "udp_bind failed: socket(): %s", strerror(errno));
		return -1;
	}

	if (addr && atoi(addr) >= 239)
	{
		struct ip_mreq mreq;

		mreq.imr_multiaddr.s_addr = inet_addr(addr);
		mreq.imr_interface.s_addr = htonl(INADDR_ANY);
		LOG("setting multicast for %s", addr);
		if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))
				== -1)
		{
			LOGL(0, "membership error: %s", strerror(errno));
		}
	}
	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0)
	{
		LOGL(0, "udp_bind failed: setsockopt(SO_REUSEADDR): %s",
				strerror(errno));
		return -1;
	}

	if (bind(sock, (struct sockaddr *) &serv, sizeof(serv)) < 0)
	{
		LOGL(0, "udp_bind: failed: bind() on host %s port %d: error %s", addr,
				port, strerror(errno));
		return -1;
	}

	set_linux_socket_timeout(sock);

	LOGL(1, "New UDP socket %d bound to %s:%d", sock, inet_ntoa(serv.sin_addr),
			ntohs(serv.sin_port));
	return sock;
}
예제 #4
0
파일: common.c 프로젝트: jam2in/arcus-misc
int
parse_hostport(char *addr_str, struct sockaddr_in *addr, char **host_out)
{
  char *host, *c, *dup;
  int port, err = -1;
  
  dup = strdup(addr_str);
  if (dup == NULL) {
    print_log("failed to allocate address buffer. len=%ld",
      strlen(addr_str));
    goto exit;
  }
  c = dup;
  host = c;
  while (*c != ':' && *c != '\0')
    c++;
  if (*c == '\0') {
    print_log("bad address string %s", addr_str);
    goto exit;
  }
  *c++ = '\0';
  errno = 0;
  port = strtol(c, NULL, 10);
  if (errno != 0) {
    ERRLOG(errno, "error while parsing port number (strtol). address=%s",
      addr_str);
    goto exit;
  }
  if (port <= 0 || port >= 64*1024) {
    print_log("bad port %d in address string %s", port, addr_str);
    goto exit;
  }
  memset(addr, 0, sizeof(*addr));
  if (0 != fill_sockaddr(host, addr)) {
    print_log("cannot find the address for host %s", host);
    goto exit;
  }
  addr->sin_port = htons(port);
  err = 0;
exit:
  if (err == 0 && host_out != NULL)
    *host_out = host;
  else if (dup)
    free(dup);
  return err;
}
예제 #5
0
int udp_bind_connect(char *src, int sport, char *dest, int dport,
		struct sockaddr_in *serv)
{
	int sock;
	sock = udp_bind(src, sport);
	if (sock < 0)
		return sock;
	fill_sockaddr(serv, dest, dport);
	if (connect(sock, (struct sockaddr *) serv, sizeof(*serv)) < 0)
	{
		LOGL(0, "udp_bind_connect: failed: bind(): %s", strerror(errno));
		return -1;
	}
	LOG("New UDP socket %d connected to %s:%d", sock, inet_ntoa(serv->sin_addr),
			ntohs(serv->sin_port));

	return sock;
}
예제 #6
0
int tcp_connect(char *addr, int port, struct sockaddr_in *serv, int blocking)
{
	struct sockaddr_in sv;
	int sock, optval = 1;

	if (serv == NULL)
		serv = &sv;
	if (!fill_sockaddr(serv, addr, port))
		return -1;
	sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock < 0)
	{
		LOGL(0, "tcp_connect failed: socket() %s", strerror(errno));
		return -1;
	}

	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0)
	{
		LOGL(0, "tcp_connect: setsockopt(SO_REUSEADDR): %s", strerror(errno));
		close(sock);
		return -1;
	}

	set_linux_socket_timeout(sock);

	if (blocking)
	{
		int flags = fcntl(sock, F_GETFL, 0);
		fcntl(sock, F_SETFL, flags | O_NONBLOCK);
	}

	if (connect(sock, (struct sockaddr *) serv, sizeof(*serv)) < 0)
	{
		if (errno != EINPROGRESS)
		{
			LOGL(0, "tcp_connect: failed: connect to %s:%d failed: %s", addr,
					port, strerror(errno));
			close(sock);
			return -1;
		}
	}
	LOG("New TCP socket %d connected to %s:%d", sock, addr, port);
	return sock;
}
예제 #7
0
파일: common.c 프로젝트: jam2in/arcus-misc
int
sockaddr_from_proc_name(char *name, struct sockaddr_in *addr)
{
  /* name always starts like host:port-... */
  char *c = name, *colon = NULL, *dash = NULL;
  int port, err = -1;
  
  while (*c != '\0' && *c != ':')
    c++;
  if (*c == ':') {
    colon = c;
    while (*c != '\0' && *c != '-')
      c++;
    if (*c == '-') {
      dash = c;
      /* null terminate temporarily... */
      *colon = '\0';
      *dash = '\0';
      c = colon+1;
      port = 0;
      while (*c != '\0') {
        if (*c >= '0' && *c <= '9') {
          port = port * 10 + (*c - '0');
        }
        else {
          port = -1;
          break;
        }
        c++;
      }
      if (port > 0 && port < 64*1024 && 0 == fill_sockaddr(name, addr)) {
        addr->sin_port = htons(port);
        err = 0;
      }
    }
  }
  if (colon)
    *colon = ':';
  if (dash)
    *dash = '-';
  return err;
}
예제 #8
0
char *
getlocalip()
{
	//      if(localip[0]!=0)return localip;

	const char *dest = opts.disc_host, *h;
	int port = 1900;

	struct sockaddr_in serv;

	int sock = socket(AF_INET, SOCK_DGRAM, 0);

	//Socket could not be created
	if (sock < 0)
	{
		LOG("getlocalip: Cannot create socket: %s", strerror(errno));
		return localip;
	}

	fill_sockaddr(&serv, (char *) dest, port);
	int err = connect(sock, (const struct sockaddr *) &serv, sizeof(serv));
	if (err)
	{
		LOG("getlocalip: Error '%s'' during connect", strerror(errno));
		memset(localip, 0, sizeof(localip));
	}
	else
	{
		h = get_sock_shost(sock);
		if (h)
			strcpy(localip, h);
	}
	close(sock);
	return localip;

}
예제 #9
0
int
getaddrinfo(const char *node, const char *service,
                    const struct addrinfo *hints,
                    struct addrinfo **res)
{
  struct hostent *host;
  struct servent *serv;
  int count, i;
  int port;
  char *name;
  size_t addrlen;
  char *addrs;
  struct addrinfo *addrinfos;

  host = gethostbyname(node);
  if (! host
      || (hints->ai_family != AF_UNSPEC
          && host->h_addrtype != hints->ai_family))
    return -1;

  count = 1;
#ifdef h_addr
  while (host->h_addr_list[count])
    ++count;
#endif  /* h_addr */

  serv = getservbyname(service, (hints->ai_socktype == SOCK_STREAM
                                 ? "tcp" : "udp"));
  port = serv ? serv->s_port : htons(atoi(service));

  if (host->h_name)
    {
      size_t name_len = strlen(host->h_name);
      name = (char *) malloc(name_len + 1);
      memcpy(name, host->h_name, name_len + 1);
    }
  else
    {
      name = NULL;
    }

#ifdef AF_INET6
  if (host->h_addrtype == AF_INET6)
    fill_sockaddr6(host, port, count, addrlen, addrs);
  else
#endif  /* AF_INET6 */
    fill_sockaddr(host, port, count, addrlen, addrs);


  addrinfos = (struct addrinfo *) malloc(sizeof(*addrinfos) * count);
  addrinfos[0].ai_flags = hints->ai_flags;
  addrinfos[0].ai_family = host->h_addrtype;
  addrinfos[0].ai_socktype = hints->ai_socktype;
  addrinfos[0].ai_protocol = hints->ai_protocol;
  addrinfos[0].ai_addrlen = addrlen;
  addrinfos[0].ai_addr = (struct sockaddr *) addrs;
  addrinfos[0].ai_canonname = name;
  for (i = 1; i < count; ++i)
    {
      addrinfos[i] = addrinfos[0];

      addrinfos[i].ai_addr = (struct sockaddr *) (addrs + addrlen * i);
      addrinfos[i - 1].ai_next = &addrinfos[i];
    }
  addrinfos[i - 1].ai_next = NULL;

  *res = addrinfos;

  return 0;
}
예제 #10
0
int main(int argc,char **argv) {
    int i,srv_sock,j,retval,ptype;
    struct sockaddr_in srv_sa;
    int clientfds[MAX_CLIENTS];
    char *clientsas[MAX_CLIENTS];
    int client_cnt = 0;
    int block_size = 1024;
    int maxfd = 0;
    int c;
    char *srvhost = NULL;
    short srvport = DEF_SRV_PORT;
    int proto = DEF_PROTO;
    int debug = 0;
    char *buf = NULL;
    fd_set rfds;
    fd_set static_rfds;

    /* grab some quick args, hostname, port, tcp, udp... */
    while ((c = getopt(argc,argv,"h:p:tudb:")) != -1) {
	switch(c) {
	case 'h':
	    srvhost = optarg;
	    break;
	case 'p':
	    srvport = atoi(optarg);
	    break;
	case 't':
	    proto = SOCK_STREAM;
	    break;
	case 'u':
	    proto = SOCK_DGRAM;
	    fatal("no udp support yet!");
	    break;
	case 'd':
	    ++debug;
	    break;
	case 'b':
	    block_size = atoi(optarg);
	    break;
	default:
	    break;
	}
    }

    if ((buf = (char *)malloc(sizeof(char)*block_size)) == NULL) {
	efatal("no memory for data buf");
    }
    
    if ((retval = fill_sockaddr(srvhost,srvport,&srv_sa)) != 0) {
	if (retval == -1) {
	    fatal("bad port");
	}
	else {
	    efatal("host lookup failed");
	}
    }

    /* startup server... */
    if ((srv_sock = socket(AF_INET,proto,0)) == -1) {
	efatal("could not get socket");
    }

    if (bind(srv_sock,
	     (struct sockaddr *)&srv_sa,
	     sizeof(struct sockaddr_in)
	     ) < 0) {
	efatal("could not bind");
    }

    if (proto == PROTO_TCP) {
	if (listen(srv_sock,8) < 0) {
	    efatal("could not listen");
	}
    }

    /* daemonize... */
    if (!debug) {
	daemon(0,0);
    }

    for (i = 0; i < MAX_CLIENTS; ++i) {
	clientfds[i] = -1;
	clientsas[i] = (char *)malloc(MAX_NAME_LEN + 1);
    }

    FD_ZERO(&static_rfds);
    FD_SET(srv_sock,&static_rfds);
    maxfd = srv_sock;
    
    /* listen and read forever */
    while (1) {
	/* reset fdsets */
	memcpy(&rfds,&static_rfds,sizeof(static_rfds));

	retval = select(maxfd+1,&rfds,NULL,NULL,NULL);
	
	if (retval > 0) {
	    if (FD_ISSET(srv_sock,&rfds)) {
		struct sockaddr_in client_sin;
		socklen_t slen;
		int client_fd;

		slen = sizeof(client_sin);

		if ((client_fd = accept(srv_sock,
					(struct sockaddr *)&client_sin,
					&slen)) < 0) {
		    warn("accept failed");
		}
		else if (client_cnt >= MAX_CLIENTS) {
		    warn("already at max clients");
		}
		else {
		    /* add new client... */
		    for (i = 0; i < MAX_CLIENTS; ++i) {
			if (clientfds[i] == -1) {
			    break;
			}
		    }
		    
		    clientfds[i] = client_fd;
		    if (client_fd > maxfd) {
			maxfd = client_fd;
		    }
		    
		    FD_SET(client_fd,&static_rfds);
		    
		    if (debug) {
			fprintf(stdout,
				"connect from %s:%d\n",
				inet_ntoa(client_sin.sin_addr),
				ntohs(client_sin.sin_port));
		    }
		    
		    char *addr = inet_ntoa(client_sin.sin_addr);
		    int addrlen = strlen(addr);
		    
		    strncpy(clientsas[i],
			    addr,
			    (addrlen > MAX_NAME_LEN)?MAX_NAME_LEN:addrlen);
		    /* null term if strncpy couldn't */
		    if (addrlen > MAX_NAME_LEN) {
			clientsas[i][MAX_NAME_LEN] = '\0';
		    }
		    
		    ++client_cnt;
		}
	    }
	    else {
		for (i = 0; i < MAX_CLIENTS; ++i) {
		    if (clientfds[i] > -1) {
			if (FD_ISSET(clientfds[i],&rfds)) {
			    /* read a block, or as much as possible */
			    retval = read(clientfds[i],buf,block_size);

			    /* dead client, pretty much */
			    if (retval <= 0) {
				if (debug) {
				    fprintf(stdout,
					    "disconnect from %s\n",
					    clientsas[i]);
				}

				close(clientfds[i]);
				FD_CLR(clientfds[i],&static_rfds);
				clientfds[i] = -1;

				--client_cnt;
			    }
			    else if (debug > 2 ) {
				fprintf(stdout,
					"DEBUG: read %d bytes from %s\n",
					retval,
					clientsas[i]);
			    }
			}
		    }
		}
	    }
	}
	else if (retval < 0) {
	    /* error... */
	    ewarn("error in select");
	}
    }

    return -1;
}