示例#1
0
/* Connect to socket with ip address */
GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip)
{
	union sockaddr_union so;
	int handle, ret, opt = 1;

	if (my_ip != NULL && ip->family != my_ip->family) {
		g_warning("net_connect_ip(): ip->family != my_ip->family");
                my_ip = NULL;
	}

	/* create the socket */
	memset(&so, 0, sizeof(so));
        so.sin.sin_family = ip->family;
	handle = socket(ip->family, SOCK_STREAM, 0);

	if (handle == -1)
		return NULL;

	/* set socket options */
#ifndef WIN32
	fcntl(handle, F_SETFL, O_NONBLOCK);
#endif
	setsockopt(handle, SOL_SOCKET, SO_REUSEADDR,
		   (char *) &opt, sizeof(opt));
	setsockopt(handle, SOL_SOCKET, SO_KEEPALIVE,
		   (char *) &opt, sizeof(opt));

	/* set our own address */
	if (my_ip != NULL) {
		sin_set_ip(&so, my_ip);
		if (bind(handle, &so.sa, SIZEOF_SOCKADDR(so)) == -1) {
			/* failed, set it back to INADDR_ANY */
			sin_set_ip(&so, NULL);
			bind(handle, &so.sa, SIZEOF_SOCKADDR(so));
		}
	}

	/* connect */
	sin_set_ip(&so, ip);
	sin_set_port(&so, port);
	ret = connect(handle, &so.sa, SIZEOF_SOCKADDR(so));

#ifndef WIN32
	if (ret < 0 && errno != EINPROGRESS)
#else
	if (ret < 0 && WSAGetLastError() != WSAEWOULDBLOCK)
#endif
	{
		int old_errno = errno;
		close(handle);
		errno = old_errno;
		return NULL;
	}

	return g_io_channel_new(handle);
}
示例#2
0
/* Listen for connections on a socket. if `my_ip' is NULL, listen in any
   address. */
GIOChannel *net_listen(IPADDR *my_ip, int *port)
{
	union sockaddr_union so;
	int ret, handle, opt = 1;
	socklen_t len;

	g_return_val_if_fail(port != NULL, NULL);

	memset(&so, 0, sizeof(so));
	sin_set_port(&so, *port);
	sin_set_ip(&so, my_ip);

	/* create the socket */
	handle = socket(so.sin.sin_family, SOCK_STREAM, 0);
#ifdef HAVE_IPV6
	if (handle == -1 && (errno == EINVAL || errno == EAFNOSUPPORT)) {
		/* IPv6 is not supported by OS */
		so.sin.sin_family = AF_INET;
		so.sin.sin_addr.s_addr = INADDR_ANY;

		handle = socket(AF_INET, SOCK_STREAM, 0);
	}
#endif
	if (handle == -1)
		return NULL;

	/* set socket options */
#ifndef WIN32
	fcntl(handle, F_SETFL, O_NONBLOCK);
#endif
	setsockopt(handle, SOL_SOCKET, SO_REUSEADDR,
		   (char *) &opt, sizeof(opt));
	setsockopt(handle, SOL_SOCKET, SO_KEEPALIVE,
		   (char *) &opt, sizeof(opt));

	/* specify the address/port we want to listen in */
	ret = bind(handle, &so.sa, SIZEOF_SOCKADDR(so));
	if (ret >= 0) {
		/* get the actual port we started listen */
		len = SIZEOF_SOCKADDR(so);
		ret = getsockname(handle, &so.sa, &len);
		if (ret >= 0) {
			*port = sin_get_port(&so);

			/* start listening */
			if (listen(handle, 1) >= 0)
                                return g_io_channel_new(handle);
		}

	}

        /* error */
	close(handle);
	return NULL;
}
示例#3
0
struct addrinfo CreateAddrinfo( sockaddr_u* sock) {
	struct addrinfo a;
	a.ai_family = sock->sa.sa_family;
	a.ai_addrlen = SIZEOF_SOCKADDR(a.ai_family);
	a.ai_addr = &sock->sa;
	return a;
}
示例#4
0
struct addrinfo CreateAddrinfo(sockaddr_u* sock) {
	struct addrinfo a;
	memset(&a, '\0', sizeof(struct addrinfo));
	a.ai_family = sock->sa.sa_family;
	a.ai_addrlen = SIZEOF_SOCKADDR(a.ai_family);
	a.ai_addr = &sock->sa;
	return a;
}
示例#5
0
bool WSocket::ipToStringW(const SOCKADDR_STORAGE *sockAddr, LPWSTR buffer)
{
  DWORD size = MAX_PATH;
  if(CWA(ws2_32, WSAAddressToStringW)((LPSOCKADDR)sockAddr, SIZEOF_SOCKADDR(sockAddr->ss_family), NULL, buffer, &size) != 0)
  {
    Str::_CopyW(buffer, L"0:0", 3);
    return false;
  }
  return true;
}
示例#6
0
SOCKET WSocket::tcpConnect(const SOCKADDR_STORAGE *sockAddr)
{
  SOCKET s = CWA(ws2_32, socket)(sockAddr->ss_family, SOCK_STREAM, IPPROTO_TCP);
  if(s != INVALID_SOCKET)
  {
    if(CWA(ws2_32, connect)(s, (sockaddr *)sockAddr, SIZEOF_SOCKADDR(sockAddr->ss_family)) != 0)
    {
      CWA(ws2_32, closesocket)(s);
      s = INVALID_SOCKET;
    }
  }
  return s;
}
示例#7
0
SOCKET WSocket::udpListen(const SOCKADDR_STORAGE *sockAddr)
{
  SOCKET s = CWA(ws2_32, socket)(sockAddr->ss_family, SOCK_DGRAM, IPPROTO_UDP);
  if(s != INVALID_SOCKET)
  {
    if(CWA(ws2_32, bind)(s, (sockaddr *)sockAddr, SIZEOF_SOCKADDR(sockAddr->ss_family)) != 0)
    {
      CWA(ws2_32, closesocket)(s);
      s = INVALID_SOCKET;
    }
  }
  return s;
}
示例#8
0
SOCKET WSocket::tcpListen(const SOCKADDR_STORAGE *sockAddr, int backlog)
{
  SOCKET s = CWA(ws2_32, socket)(sockAddr->ss_family, SOCK_STREAM, IPPROTO_TCP);
  if(s != INVALID_SOCKET)
  {
    if(CWA(ws2_32, bind)(s, (sockaddr *)sockAddr, SIZEOF_SOCKADDR(sockAddr->ss_family)) != 0 || CWA(ws2_32, listen)(s, backlog) != 0)
    {
      CWA(ws2_32, closesocket)(s);
      s = INVALID_SOCKET;
    }
  }
  return s;
}
示例#9
0
int silc_net_udp_send(SilcStream stream,
		      const char *remote_ip_addr, int remote_port,
		      const unsigned char *data, SilcUInt32 data_len)
{
  SilcSocketStream sock = stream;
  SilcSockaddr remote;
  int ret;

  SILC_LOG_DEBUG(("Sending data to UDP socket %d", sock->sock));

  /* Set sockaddr */
  if (!silc_net_set_sockaddr(&remote, remote_ip_addr, remote_port))
    return -2;

  /* Send */
  ret = sendto(sock->sock, data, data_len, 0, &remote.sa,
	       SIZEOF_SOCKADDR(remote));
  if (ret < 0) {
    if (errno == EAGAIN || errno == EINTR) {
      SILC_LOG_DEBUG(("Could not send immediately, will do it later"));
      silc_schedule_set_listen_fd(sock->schedule, sock->sock,
				  SILC_TASK_READ | SILC_TASK_WRITE, FALSE);
      return -1;
    }
    SILC_LOG_DEBUG(("Cannot send to UDP socket: %s", strerror(errno)));
    silc_schedule_unset_listen_fd(sock->schedule, sock->sock);
    sock->sock_error = errno;
    return -2;
  }

  SILC_LOG_DEBUG(("Sent data %d bytes", ret));
  if (silc_schedule_get_fd_events(sock->schedule, sock->sock) &
      SILC_TASK_WRITE)
    silc_schedule_set_listen_fd(sock->schedule, sock->sock,
				SILC_TASK_READ, FALSE);

  return ret;
}
示例#10
0
文件: ntpdc.c 项目: pexip/os-ntp
/*
 * getnetnum - given a host name, return its net number
 *	       and (optional) full name
 */
static int
getnetnum(
	const char *hname,
	sockaddr_u *num,
	char *fullhost,
	int af
	)
{
	int sockaddr_len;
	struct addrinfo hints, *ai = NULL;

	sockaddr_len = SIZEOF_SOCKADDR(af);
	memset((char *)&hints, 0, sizeof(struct addrinfo));
	hints.ai_flags = AI_CANONNAME;
#ifdef AI_ADDRCONFIG
	hints.ai_flags |= AI_ADDRCONFIG;
#endif
	
	/* decodenetnum only works with addresses */
	if (decodenetnum(hname, num)) {
		if (fullhost != 0) {
			getnameinfo(&num->sa, sockaddr_len, 
				    fullhost, sizeof(fullhost), NULL, 0, 
				    NI_NUMERICHOST); 
		}
		return 1;
	} else if (getaddrinfo(hname, "ntp", &hints, &ai) == 0) {
		memmove((char *)num, ai->ai_addr, ai->ai_addrlen);
		if (fullhost != 0)
			(void) strcpy(fullhost, ai->ai_canonname);
		return 1;
	} else {
		(void) fprintf(stderr, "***Can't find host %s\n", hname);
		return 0;
	}
	/*NOTREACHED*/
}
示例#11
0
SilcStream
silc_net_udp_connect(const char *local_ip_addr, int local_port,
		     const char *remote_ip_addr, int remote_port,
		     SilcSchedule schedule)
{
  SilcStream stream;
  SilcSockaddr server;
  int sock = -1, rval;
  const char *ipany = "0.0.0.0";

  SILC_LOG_DEBUG(("Creating UDP stream"));

  if (!schedule)
    goto err;

  /* Bind to local addresses */
  SILC_LOG_DEBUG(("Binding to local address %s",
		  local_ip_addr ? local_ip_addr : ipany));

  /* Set sockaddr for server */
  if (!silc_net_set_sockaddr(&server, local_ip_addr ? local_ip_addr : ipany,
			     local_port))
    goto err;

  /* Create the socket */
  sock = socket(server.sin.sin_family, SOCK_DGRAM, 0);
  if (sock < 0) {
    SILC_LOG_ERROR(("Cannot create socket: %s", strerror(errno)));
    goto err;
  }

  /* Set the socket options */
  rval = silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
  if (rval < 0) {
    SILC_LOG_ERROR(("Cannot set socket options: %s", strerror(errno)));
    goto err;
  }
#ifdef SO_REUSEPORT
  rval = silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEPORT, 1);
  if (rval < 0) {
    SILC_LOG_ERROR(("Cannot set socket options: %s", strerror(errno)));
    goto err;
  }
#endif /* SO_REUSEPORT */

  /* Bind the listener socket */
  rval = bind(sock, &server.sa, SIZEOF_SOCKADDR(server));
  if (rval < 0) {
    SILC_LOG_DEBUG(("Cannot bind socket: %s", strerror(errno)));
    goto err;
  }

  /* Set to connected state if remote address is provided. */
  if (remote_ip_addr && remote_port) {
    if (!silc_net_set_sockaddr(&server, remote_ip_addr, remote_port))
      goto err;

    rval = connect(sock, &server.sa, SIZEOF_SOCKADDR(server));
    if (rval < 0) {
      SILC_LOG_DEBUG(("Cannot connect UDP stream: %s", strerror(errno)));
      goto err;
    }
  }

  /* Set send and receive buffer size */
#ifdef SO_SNDBUF
  rval = silc_net_set_socket_opt(sock, SOL_SOCKET, SO_SNDBUF, 765535);
  if (rval < 0) {
    rval = silc_net_set_socket_opt(sock, SOL_SOCKET, SO_SNDBUF, 65535);
    if (rval < 0) {
      SILC_LOG_ERROR(("Cannot set socket options: %s", strerror(errno)));
      goto err;
    }
  }
#endif /* SO_SNDBUF */
#ifdef SO_RCVBUF
  rval = silc_net_set_socket_opt(sock, SOL_SOCKET, SO_RCVBUF, 765535);
  if (rval < 0) {
    rval = silc_net_set_socket_opt(sock, SOL_SOCKET, SO_RCVBUF, 65535);
    if (rval < 0) {
      SILC_LOG_ERROR(("Cannot set socket options: %s", strerror(errno)));
      goto err;
    }
  }
#endif /* SO_RCVBUF */

  /* Encapsulate into socket stream */
  stream =
    silc_socket_udp_stream_create(sock, local_ip_addr ?
				  silc_net_is_ip6(local_ip_addr) : FALSE,
				  remote_ip_addr ? TRUE : FALSE, schedule);
  if (!stream)
    goto err;

  SILC_LOG_DEBUG(("UDP stream created, fd=%d", sock));
  return stream;

 err:
  if (sock != -1)
    close(sock);
  return NULL;
}
示例#12
0
SilcNetListener
silc_net_tcp_create_listener(const char **local_ip_addr,
			     SilcUInt32 local_ip_count, int port,
			     SilcBool lookup, SilcBool require_fqdn,
			     SilcSchedule schedule,
			     SilcNetCallback callback, void *context)
{
  SilcNetListener listener = NULL;
  SilcSockaddr server;
  int i, sock, rval;
  const char *ipany = "0.0.0.0";

  SILC_LOG_DEBUG(("Creating TCP listener"));

  if (port < 0 || !schedule || !callback)
    goto err;

  listener = silc_calloc(1, sizeof(*listener));
  if (!listener)
    return NULL;
  listener->schedule = schedule;
  listener->callback = callback;
  listener->context = context;
  listener->require_fqdn = require_fqdn;
  listener->lookup = lookup;

  if (local_ip_count > 0) {
    listener->socks = silc_calloc(local_ip_count, sizeof(*listener->socks));
    if (!listener->socks)
      return NULL;
  } else {
    listener->socks = silc_calloc(1, sizeof(*listener->socks));
    if (!listener->socks)
      return NULL;

    local_ip_count = 1;
  }

  /* Bind to local addresses */
  for (i = 0; i < local_ip_count; i++) {
    SILC_LOG_DEBUG(("Binding to local address %s:%d",
		    local_ip_addr ? local_ip_addr[i] : ipany, port));

    /* Set sockaddr for server */
    if (!silc_net_set_sockaddr(&server,
			       local_ip_addr ? local_ip_addr[i] : ipany,
			       port))
      goto err;

    /* Create the socket */
    sock = socket(server.sin.sin_family, SOCK_STREAM, 0);
    if (sock < 0) {
      SILC_LOG_ERROR(("Cannot create socket: %s", strerror(errno)));
      goto err;
    }

    /* Set the socket options */
    rval = silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
    if (rval < 0) {
      SILC_LOG_ERROR(("Cannot set socket options: %s", strerror(errno)));
      close(sock);
      goto err;
    }

    /* Bind the listener socket */
    rval = bind(sock, &server.sa, SIZEOF_SOCKADDR(server));
    if (rval < 0) {
      SILC_LOG_ERROR(("Cannot bind socket: %s", strerror(errno)));
      close(sock);
      goto err;
    }

    /* Specify that we are listenning */
    rval = listen(sock, 64);
    if (rval < 0) {
      SILC_LOG_ERROR(("Cannot set socket listenning: %s", strerror(errno)));
      close(sock);
      goto err;
    }

    /* Set the server socket to non-blocking mode */
    silc_net_set_socket_nonblock(sock);

    /* Schedule for incoming connections */
    silc_schedule_task_add_fd(schedule, sock, silc_net_accept, listener);

    SILC_LOG_DEBUG(("TCP listener created, fd=%d", sock));
    listener->socks[i] = sock;
    listener->socks_count++;
  }

  return listener;

 err:
  if (listener)
    silc_net_close_listener(listener);
  return NULL;
}