Пример #1
0
void WTConnection::disconnect(void)
{
	if(!this->connecting && !this->connected)
	{
		return;
	};
	
	this->connecting = false;
	this->connected = false;

	if(this->socket != 0)
		close_portable(this->socket);
#ifndef NO_SSL
	if(this->ssl_socket != NULL)
	{
		if(BIO_reset(this->ssl_socket) != 0)
			warning_error("failed to reset socket");
		BIO_free_all(this->ssl_socket);
		this->ssl_socket = NULL;
		this->ssl = NULL;
	};
	if(this->ssl_ctx != NULL)
	{
		SSL_CTX_free(this->ssl_ctx);
		this->ssl_ctx = NULL;
	};
#endif
	delegate_status(WTHTTP_Closed);

	if(this->addr_info != NULL)
	{
		freeaddrinfo(this->addr_info);
		this->addr_info = NULL;
	};

	if(this->uri != NULL)
	{
		free(this->uri);
		this->uri = NULL;
	};

	if(this->domain != NULL)
	{
		free(this->domain);
		this->domain = NULL;
	};

	if(this->protocol != NULL)
	{
		free(this->protocol);
		this->protocol = NULL;
	};
}
Пример #2
0
socket_t uplink_connect(char *uplink, uint16_t port, char *vhost)
{
	socket_t sock;
	int error, flags;
    unsigned int optval;
    struct addrinfo *res = NULL,
                    hints;

    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    StartWSA();

    if ((error = getaddrinfo(uplink, NULL, &hints, &res)))
        sigyn_fatal("Cannot resolve hostname(%s): %s", uplink, gai_strerror(error));
    if (res->ai_addr == NULL)
    {
        freeaddrinfo(res);
        sigyn_fatal("Cannot resolve hostname (%s).");
    }

    logger(LOG_STATUS, "Attempting to connect to %s:%d", uplink, port);
    if (!(sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol)))
    {
        freeaddrinfo(res);
        sigyn_fatal("Unable to create socket.");
    }

    if (sock > me.maxfd)
        me.maxfd = sock;

    if (vhost != NULL)
    {
        struct addrinfo *bindres = NULL;
        
        if ((error = getaddrinfo(vhost, NULL, &hints, &bindres)))
        {
            freeaddrinfo(res);
            close_portable(sock);
            sigyn_fatal("Cannot resolve vhost (%s): %s", vhost, gai_strerror(error));
        }
        if (bindres->ai_addr == NULL)
        {
            freeaddrinfo(res);
            freeaddrinfo(bindres);
            sigyn_fatal("Cannot resolve vhost (%s).");
        }

        optval = 1;
        setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&optval, sizeof(optval));

        if (bind(sock, bindres->ai_addr, bindres->ai_addrlen) < 0)
        {
            freeaddrinfo(res);
            freeaddrinfo(bindres);
            close_portable(sock);
            sigyn_fatal("Unable to bind to vhost (%s): %s", vhost, strerror(errno));
        }

        freeaddrinfo(bindres);
    }

    logger(LOG_DEBUG, "Setting file descriptor %d as non-blocking.", sock);

#ifdef _WIN32
    ioctlsocket(sock, FIONBIO, 1);
#else
    flags = fcntl(sock, F_GETFL, 0);
    flags |= O_NONBLOCK;
    fcntl(sock, F_SETFL, flags);
#endif

    switch(res->ai_family)
    {
        case AF_INET:
            ((struct sockaddr_in *) res->ai_addr)->sin_port = htons(port);
            break;
        case AF_INET6:
            ((struct sockaddr_in6 *) res->ai_addr)->sin6_port = htons(port);
            break;
    }

    if ((connect(sock, res->ai_addr, res->ai_addrlen) == -1)
            && errno != EINPROGRESS && errno != EINTR)
    {
        close_portable(sock);
        freeaddrinfo(res);
        if (vhost)
            sigyn_fatal("Failed to connect to %s (Using vhost %s): %s",
                    uplink, vhost, strerror(errno));
        else
            sigyn_fatal("Failed to connect to %s: %s", uplink, strerror(errno));
    }

    freeaddrinfo(res);

    return sock;
}
Пример #3
0
void uplink_disconnect(void)
{
    if(me.uplink.connected == true)
        close_portable(me.uplink.sock);
}
Пример #4
0
bool WTConnection::connect(const char *url)
{
	int addr_result;
	struct addrinfo hint;
#ifdef _WIN32
	DWORD timeout_msec;
#else
	struct timeval tv;
#endif
	char ports[6];
	
	if(this->connecting)
	{
		return false;
	};

	if(this->connected)
	{
		this->disconnect();
	};
	
	this->connecting = true;

	if(!this->parse_url(url))
	{
		fprintf(stderr, "can't parse URL %s\n", url);
		last_error = "unparsable URL";
		delegate_status(WTHTTP_Error);
		this->connecting = false;
		return false;
	};

	if(strcmp("https", this->protocol) == 0)
	{
		return connect_https();
	};

	/* Ensure cleanliness */
	memset(&hint, 0, sizeof(struct addrinfo));
	hint.ai_family = AF_UNSPEC;
	hint.ai_socktype = SOCK_STREAM;
	
	delegate_status(WTHTTP_Resolving);
	snprintf(ports, 6, "%d", this->port);
	if( (addr_result = getaddrinfo(this->domain,
					ports,
					&hint,
					&(this->addr_info))) != 0)
	{
		last_error = gai_strerror(addr_result);
		fprintf(stderr, "can't resolve %s: %s\n",
			this->domain,
			last_error);
		delegate_status(WTHTTP_Error);
		free(this->uri);
		free(this->domain);
		free(this->protocol);
		this->connecting = false;
		return false;
	};

	delegate_status(WTHTTP_Connecting);
	this->socket = ::socket(this->addr_info->ai_family,
				this->addr_info->ai_socktype,
				this->addr_info->ai_protocol);

#ifdef _WIN32
	timeout_msec = 30000;

	if(::setsockopt(this->socket, SOL_SOCKET, SO_RCVTIMEO,
			reinterpret_cast<char *>(&timeout_msec), sizeof(DWORD)) == -1)
#else
	tv.tv_sec = 30;
	tv.tv_usec = 0;
	
	if(::setsockopt(this->socket, SOL_SOCKET, SO_RCVTIMEO,
			reinterpret_cast<char *>(&tv), sizeof(tv)) == -1)
#endif
	{
		warning_error("couldn't set recv timeout -- expect delays");
	}
	
	if(::connect(this->socket,
			this->addr_info->ai_addr,
			this->addr_info->ai_addrlen) == -1)
	{
		last_error = strerror(errno);
		fprintf(stderr, "can't connect to %s: %s\n",
			this->domain,
			last_error);
		delegate_status(WTHTTP_Error);
		close_portable(this->socket);
		freeaddrinfo(this->addr_info);
		free(this->uri);
		free(this->domain);
		free(this->protocol);
		this->connecting = false;
		return false;
	};

	this->connected = true;
	this->connecting = false;
	delegate_status(WTHTTP_Connected);

	return true;
}