Exemple #1
0
/*
 * connect()
 *  "connect" will attempt to open a connection on a foreign IP address and
 *  foreign port address.  This is achieved by specifying the foreign IP
 *  address and foreign port number in the "servaddr".
 */
int W32_CALL connect (int s, const struct sockaddr *servaddr, int addrlen)
{
  struct   sockaddr_in  *addr   = (struct sockaddr_in*) servaddr;
  struct   sockaddr_in6 *addr6  = (struct sockaddr_in6*) servaddr;
  struct   Socket       *socket = _socklist_find (s);
  volatile int rc, sa_len;
  BOOL     is_ip6;

  SOCK_PROLOGUE (socket, "\nconnect:%d", s);

  is_ip6 = (socket->so_family == AF_INET6);
  sa_len = is_ip6 ? sizeof(*addr6) : sizeof(*addr);

  if (_sock_chk_sockaddr(socket, servaddr, addrlen) < 0)
     return (-1);

  if (socket->so_type == SOCK_STREAM)
  {
    if (socket->so_state & SS_ISCONNECTED)
    {
      SOCK_DEBUGF ((", EISCONN"));
      SOCK_ERRNO (EISCONN);
      return (-1);
    }
    if (socket->so_options & SO_ACCEPTCONN)
    {
      SOCK_DEBUGF ((", EOPNOTSUPP (listen sock)"));
      SOCK_ERRNO (EOPNOTSUPP);
      return (-1);
    }
    if (!is_ip6 && IN_MULTICAST(ntohl(addr->sin_addr.s_addr)))
    {
      SOCK_DEBUGF ((", EINVAL (mcast)"));
      SOCK_ERRNO (EINVAL);
      return (-1);
    }
    else if (is_ip6 && IN6_IS_ADDR_MULTICAST(&addr6->sin6_addr))
    {
      SOCK_DEBUGF ((", EINVAL (mcast)"));
      SOCK_ERRNO (EINVAL);
      return (-1);
    }
  }

  if (socket->remote_addr)
  {
    if ((socket->so_type == SOCK_STREAM) &&
        (socket->so_state & SS_NBIO))
       return nblk_connect (socket);

    SOCK_DEBUGF ((", connect already done!"));
    SOCK_ERRNO (EISCONN);
    return (-1);
  }

  socket->remote_addr = (struct sockaddr_in*) SOCK_CALLOC (sa_len);
  if (!socket->remote_addr)
  {
    SOCK_DEBUGF ((", ENOMEM (rem)"));
    SOCK_ERRNO (ENOMEM);
    return (-1);
  }

#if defined(USE_IPV6)
  if (is_ip6)
  {
    struct sockaddr_in6 *ra = (struct sockaddr_in6*)socket->remote_addr;

    ra->sin6_family = AF_INET6;
    ra->sin6_port   = addr6->sin6_port;
    memcpy (&ra->sin6_addr, &addr6->sin6_addr, sizeof(ra->sin6_addr));
  }
  else
#endif
  {
    socket->remote_addr->sin_family = AF_INET;
    socket->remote_addr->sin_port   = addr->sin_port;
    socket->remote_addr->sin_addr   = addr->sin_addr;
  }

  if (!socket->local_addr)
  {
    SOCK_DEBUGF ((", auto-binding"));

    socket->local_addr = (struct sockaddr_in*) SOCK_CALLOC (sa_len);
    if (!socket->local_addr)
    {
      free (socket->remote_addr);
      socket->remote_addr = NULL;
      SOCK_DEBUGF ((", ENOMEM (loc)"));
      SOCK_ERRNO (ENOMEM);
      return (-1);
    }

#if defined(USE_IPV6)
    if (is_ip6)
    {
      struct sockaddr_in6 *la = (struct sockaddr_in6*)socket->local_addr;

      la->sin6_family = AF_INET6;
      la->sin6_port   = htons (find_free_port(0,TRUE));
      memcpy (&la->sin6_addr, &in6addr_my_ip, sizeof(la->sin6_addr));
    }
    else
#endif
    {
      socket->local_addr->sin_family      = AF_INET;
      socket->local_addr->sin_port        = htons (find_free_port(0,TRUE));
      socket->local_addr->sin_addr.s_addr = htonl (my_ip_addr);
    }
  }

  SOCK_DEBUGF ((", src/dest ports: %u/%u",
                ntohs(socket->local_addr->sin_port),
                ntohs(socket->remote_addr->sin_port)));


  /* Not safe to run sock_daemon() now
   */
  _sock_crit_start();

  /* Setup SIGINT handler now.
   */
  if (_sock_sig_setup() < 0)
  {
    SOCK_ERRNO (EINTR);
    SOCK_DEBUGF ((", EINTR"));
    _sock_crit_stop();
    return (-1);
  }

  switch (socket->so_type)
  {
    case SOCK_STREAM:
         rc = tcp_connect (socket);
         break;

    case SOCK_DGRAM:
         rc = udp_connect (socket);
         break;

    case SOCK_RAW:
         rc = raw_connect (socket);
         break;

    default:
         SOCK_ERRNO (EPROTONOSUPPORT);
         rc = -1;
         break;
  }

  _sock_sig_restore();
  _sock_crit_stop();
  return (rc);
}
Exemple #2
0
void setup_stunnel(int rport, int *argc, char **argv) {
	int i, xport = 0, hport = 0, xhport = 0;

	if (! rport && argc && argv) {
		for (i=0; i< *argc; i++) {
			if (argv[i] && !strcmp(argv[i], "-rfbport")) {
				if (i < *argc - 1) {
					rport = atoi(argv[i+1]);
				}
			}
		}
	}

	if (! rport) {
		/* we do our own autoprobing then... */
		rport = find_free_port(5900, 5999);
		if (! rport) {
			goto stunnel_fail;
		}
	}

	xport = find_free_port(5950, 5999);
	if (! xport) {
		goto stunnel_fail; 
	}

	if (https_port_num > 0) {
		hport = https_port_num;
	}

	if (! hport && argc && argv) {
		for (i=0; i< *argc; i++) {
			if (argv[i] && !strcmp(argv[i], "-httpport")) {
				if (i < *argc - 1) {
					hport = atoi(argv[i+1]);
				}
			}
		}
	}

	if (! hport && http_try_it) {
		hport = find_free_port(rport-100, rport-1);
		if (! hport) {
			goto stunnel_fail;
		}
	}
	if (hport) {
		xhport = find_free_port(5850, 5899);
		if (! xhport) {
			goto stunnel_fail; 
		}
		stunnel_http_port = hport;
	}
	

	if (start_stunnel(rport, xport, hport, xhport)) {
		int tweaked = 0;
		char tmp[30];
		sprintf(tmp, "%d", xport);
		if (argc && argv) {
			for (i=0; i < *argc; i++) {
				if (argv[i] && !strcmp(argv[i], "-rfbport")) {
					if (i < *argc - 1) {
						/* replace orig value */
						argv[i+i] = strdup(tmp); 
						tweaked = 1;
						break;
					}
				}
			}
			if (! tweaked) {
				i = *argc;
				argv[i] = strdup("-rfbport");
				argv[i+1] = strdup(tmp);
				*argc += 2;
				got_rfbport = 1;
				got_rfbport_val = atoi(tmp);
			}
		}
		stunnel_port = rport;
		ssl_initialized = 1;
		return;
	}

	stunnel_fail:
	rfbLog("failed to start stunnel.\n");
	clean_up_exit(1);
}