Beispiel #1
0
/*
 * the::system::net::dns::getAddrInfo
 */
ADDRINFOW *the::system::net::dns::getAddrInfo(const wchar_t *hostNameOrAddress,
        const int addressFamily) {
    THE_STACK_TRACE;

    ADDRINFOW *retval = NULL;           // Receives the address infos.
    ADDRINFOW hints;                    // The hints about the info we want.
    int err = 0;                        // Receives lookup error codes.

    /*
     * Set the lookup hints:
     * - The input string is either a host name or a human readable IP address.
     * - Return the addresses for any protocol family.
     */
    the::zero_memory(&hints);
    hints.ai_flags = 0; //AI_CANONNAME | AI_NUMERICHOST;
    hints.ai_family = addressFamily;

#if (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0502))
    if (::GetAddrInfoW(hostNameOrAddress, NULL, &hints, &retval) != 0) {
#else /* (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0502)) */
    if (::getaddrinfo(THE_W2A(hostNameOrAddress), NULL, &hints, &retval) != 0) {
#endif /* (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0502)) */
        ASSERT(retval == NULL);
#ifdef _WIN32
        throw socket_exception(__FILE__, __LINE__);
#else /* _WIN32 */
        throw socket_exception(err, ::gai_strerror(err), __FILE__, __LINE__);
#endif /* _WIN32 */
    }

    return retval;
}
Beispiel #2
0
/*
 * the::system::net::dns::getAddrInfo
 */
struct addrinfo *the::system::net::dns::getAddrInfo(const char *hostNameOrAddress,
        const int addressFamily) {
    THE_STACK_TRACE;

    struct addrinfo *retval = NULL;     // Receives the address infos.
    struct addrinfo hints;              // The hints about the info we want.
    int err = 0;                        // Receives lookup error codes.

    /*
     * Set the lookup hints:
     * - The input string is either a host name or a human readable IP address.
     * - Return the addresses for any protocol family.
     */
    the::zero_memory(&hints);
    hints.ai_flags = 0; //AI_CANONNAME | AI_NUMERICHOST;
    hints.ai_family = addressFamily;

    if ((err = ::getaddrinfo(hostNameOrAddress, NULL, &hints, &retval)) != 0) {
        ASSERT(retval == NULL);
#ifdef _WIN32
        throw socket_exception(__FILE__, __LINE__);
#else /* _WIN32 */
        throw socket_exception(err, ::gai_strerror(err), __FILE__, __LINE__);
#endif /* _WIN32 */
    }

    return retval;
}
Beispiel #3
0
    /**
     * @brief Receive data from socket
     *
     * ...and puts it in `buf`.
     *
     * @param buf A writable memory buffer of length `len`
     * @param len Length of `buf`
     * @param flags Flags for `recv(2)`. WARNING: Throws an exception if `recv()` returns -1; this may be the case if the flag `MSG_DONTWAIT` is used.
     *
     * @returns The length of received data
     */
    ssize_t stream_client_socket::rcv(void* buf, size_t len, int flags)
    {
	ssize_t recvd;

	if ( shut_rd == true )
	    throw socket_exception(__FILE__,__LINE__,"stream_client_socket::rcv() - Socket has already been shut down!",false);

	if ( sfd == -1 )
	    throw socket_exception(__FILE__,__LINE__,"stream_client_socket::rcv() - Socket is not connected!",false);

	if ( buf == NULL || len == 0 )
	    throw socket_exception(__FILE__,__LINE__,"stream_client_socket::rcv() - Buffer or length is null!",false);

	memset(buf,0,len);

	if ( -1 == (recvd = BERKELEY::recv(sfd,buf,len,flags)) )
	{
	    if ( is_nonblocking && errno == EWOULDBLOCK )
		return -1;
	    else
		throw socket_exception(__FILE__,__LINE__,"stream_client_socket::rcv() - Error while reading!");
	}

	return recvd;
    }
    void generic_socket::reuse() {
      int on = 1;

      if (bound_ != 0) 
        throw socket_exception("can't set reuse, socket is not bound yet");

      if ( setsockopt(socket_descriptor_, SOL_SOCKET, SO_REUSEADDR, (const char *) &on, sizeof(on)) == -1)
        throw socket_exception(strerror(errno));
    }
    /**
     * @brief Connect a UNIX datagram socket
     *
     * This function connects a datagram socket; `connect(2)` says the following about this:
     *
     * > If the socket sockfd is of type SOCK_DGRAM then addr is the address to which datagrams are sent by default, and the only address from which datagrams are  received.
     *
     * @param path The path of the socket to connect this socket to.
     */
    void unix_dgram_client::connect(const char* path)
    {
	if ( sfd == -1 )
	    throw socket_exception(__FILE__,__LINE__,"unix_dgram_client::connect() - Socket has already been closed!",false);
	if ( connect_unix_dgram_socket(sfd,path) < 0 )
	    throw socket_exception(__FILE__,__LINE__,"unix_dgram_client::connect: Could not connect dgram socket!");

	_path.assign(path);

	connected = true;
    }
    void generic_socket::non_blocking() {
      int flags;

      flags = fcntl(socket_descriptor_, F_GETFL);
      if (flags == -1)
        throw socket_exception(strerror(errno));

      flags |= O_NONBLOCK;

      if (fcntl(socket_descriptor_, F_SETFL, flags) == -1)
        throw socket_exception(strerror(errno));
    }
    /**
     * @brief Set a UNIX domain datagram socket up
     *
     * @param path The path to bind this socket to
     * @param flags Flags for `socket(2)`
     */
    void unix_dgram_client::setup(const char* path, int flags)
    {
	if ( sfd != -1 )
	    throw socket_exception(__FILE__,__LINE__,"unix_dgram_client::unix_dgram_client: Socket is already set up!\n");

	sfd = create_unix_dgram_socket(path,flags);

	if ( path )
	    _path.assign(path);

	if ( sfd < 0 )
	    throw socket_exception(__FILE__,__LINE__,"unix_dgram_client::unix_dgram_client: Could not create unix dgram client socket!\n");

    }
Beispiel #8
0
 void curl_set_opt_num(CURL *curl, CURLoption option, long number)
 {
     CURLcode code = curl_easy_setopt(curl, option, number);
     if (code != CURLE_OK) {
         throw socket_exception(curl_easy_strerror(code));
     }
 }
Beispiel #9
0
void SocketSet::poll( socket_ptr_list* readable_list_ptr,
					  socket_ptr_list* writable_list_ptr,
					  socket_ptr_list* exception_list_ptr )
{
	if( m_sockets.empty() )
		return;
	if(readable_list_ptr)
		readable_list_ptr->clear();
	if(writable_list_ptr)
		writable_list_ptr->clear();
	if(exception_list_ptr)
		exception_list_ptr->clear();
	int max_fd_plus1 = m_sockets.rbegin()->first + 1;
	clear_flag();
	int n;
	if( timeout_.tv_sec < 0 )
		n = ::select( max_fd_plus1, &m_fdSet_r, &m_fdSet_w, &m_fdSet_e, 0);
	else
		n = ::select( max_fd_plus1, &m_fdSet_r, &m_fdSet_w, &m_fdSet_e, &timeout_);
	if( n > 0 ){
		for( socket_map::const_iterator iter = m_sockets.begin();
				iter != m_sockets.end(); ++iter ){
			if( readable_list_ptr && FD_ISSET( iter->first, &m_fdSet_r ) )
				readable_list_ptr->push_back( iter->second );
			if( writable_list_ptr && FD_ISSET( iter->first, &m_fdSet_w ) )
				writable_list_ptr->push_back( iter->second );
			if( exception_list_ptr && FD_ISSET( iter->first, &m_fdSet_e ) )
				exception_list_ptr->push_back( iter->second );
		}
	}
	else if( n < 0)
		throw socket_exception("select(2)", errno);
}
Beispiel #10
0
    /**
     * @brief Set a UNIX domain datagram socket up
     *
     * @param path The path to bind this socket to
     * @param flags Flags for `socket(2)`
     */
    void unix_dgram_client::setup(const char* path, int flags)
    {
	if ( sfd != -1 )
	    throw socket_exception(__FILE__,__LINE__,"unix_dgram_client::unix_dgram_client: Socket has already been set up!",false);

	sfd = create_unix_dgram_socket(path,flags);

	if ( sfd < 0 )
	    throw socket_exception(__FILE__,__LINE__,"unix_dgram_client::unix_dgram_client: Could not create unix dgram client socket!");

	if ( path )
	    _path.assign(path);


	is_nonblocking = flags & SOCK_NONBLOCK;
    }
Beispiel #11
0
 void curl_set_opt(CURL *curl, CURLoption option, const void *value)
 {
     CURLcode code = curl_easy_setopt(curl, option, value);
     if (code != CURLE_OK) {
         throw socket_exception(curl_easy_strerror(code));
     }
 }
Beispiel #12
0
 void curl_set_opt_fun(CURL *curl, CURLoption option,
                       size_t (*value)(void *, size_t, size_t, string *))
 {
     CURLcode code = curl_easy_setopt(curl, option, value);
     if (code != CURLE_OK) {
         throw socket_exception(curl_easy_strerror(code));
     }
 }
Beispiel #13
0
    /**
     * @brief Disconnect a UNIX datagram socket
     *
     * Disconnects a previously connected socket.
     *
     */
    void unix_dgram_client::deconnect(void)
    {
	if ( connect_unix_dgram_socket(sfd,0) < 0 )
	    throw socket_exception(__FILE__,__LINE__,"unix_dgram_client::deconnect: Could not disconnect dgram socket!");

	_path.clear();

	connected = false;
    }
Beispiel #14
0
int tcp_socket::recv(char* buffer, int max_len)
{
    int res = ::recv(_sock_fd, buffer, max_len, 0);
    if (res == -1 ) 
        throw socket_exception(system::error_code(errno));

    //LOG_DEBUG(main_logger, "size:%d.", res);
    return res;
}
Beispiel #15
0
int tcp_socket::send(const char* buffer, int size)
{
    int res = comno::send(_sock_fd, buffer, size);
    if (res == -1 )
        throw socket_exception(system::error_code(errno));

    //LOG_DEBUG(main_logger, "size:%d.", res);
    return res;
}
Beispiel #16
0
	ssize_t stream_client_socket::rcv(void* buf, size_t len, int flags)
	{
		ssize_t recvd;

		if ( shut_rd == true )
			throw socket_exception(__FILE__,__LINE__,"stream_client_socket::rcv() - Socket has already been shut down!\n");

		if ( sfd == -1 )
			throw socket_exception(__FILE__,__LINE__,"stream_client_socket::rcv() - Socket is not connected!\n");

		if ( buf == NULL || len == 0 )
			throw socket_exception(__FILE__,__LINE__,"stream_client_socket::rcv() - Buffer or length is null!\n");

		memset(buf,0,len);

		if ( -1 == (recvd = recv(sfd,buf,len,flags)) )
			throw socket_exception(__FILE__,__LINE__,"stream_client_socket::rcv() - Error while reading!\n");

		return recvd;
	}
Beispiel #17
0
void tcp_server::bind(const unsigned int port)
{
    struct sockaddr_in serverAddr;
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serverAddr.sin_port = htons(port);

    int res = ::bind(_sock_fd, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
    if( res == -1 )
        throw socket_exception(system::error_code(errno));
}
Beispiel #18
0
    typename selectset<SockT>::ready_socks selectset<SockT>::wait(long long microsecs)
    {
	int n = 0;

	struct timeval *timeout = NULL;

	if ( microsecs != 0 )
	{
	    struct timeval _timeout;

	    timeout = &_timeout;

	    long long micropart = microsecs % 1000000;
	    long long secpart   = microsecs / 1000000;

	    _timeout.tv_sec  = secpart;
	    _timeout.tv_usec = micropart;
	}

	n = select(highestfd(filedescriptors)+1,&readset,&writeset,NULL,timeout);

	ready_socks rwfds;

	if ( n < 0 )
	{
	    std::string err(strerror(errno));

	    throw socket_exception(__FILE__,__LINE__,"selectset::wait(): Error at select(): " + err);

	} else if ( n == 0 ) // time is over, no filedescriptor is ready
	{
	    rwfds.first.resize(0);
	    rwfds.second.resize(0);

	    return rwfds;
	}

	std::vector<int>::iterator end = filedescriptors.end();

	for ( std::vector<int>::iterator cur = filedescriptors.begin(); cur != end; cur++ )
	{
	    if ( FD_ISSET(*cur,&readset) )
		rwfds.first.push_back(fdsockmap[*cur]);

	    if ( FD_ISSET(*cur,&writeset) )
		rwfds.second.push_back(fdsockmap[*cur]);
	}

	return rwfds;
    }
Beispiel #19
0
bool tcp_server::listen(const unsigned int port)
{
    if (_sock_fd < 0) 
        return false;

    bind(port);

    int res = ::listen(_sock_fd, 10);
    if (res < 0) {
        throw socket_exception(system::error_code(errno));
    }

    _listen_port = port;
    return true;
}
Beispiel #20
0
tcp_client tcp_server::accept()
{
    struct sockaddr_in clientAddr;
    socklen_t cliLen = sizeof(clientAddr);

    int clientSocket = ::accept(_sock_fd, (struct sockaddr *)&clientAddr, &cliLen);
    if (clientSocket == -1 ) {
        throw socket_exception(system::error_code(errno));
    }

    end_point dest, src;
    dest.port = listen_port();
    src.ip = ::inet_ntoa(clientAddr.sin_addr);

    return tcp_client(clientSocket, src, dest);
}
Beispiel #21
0
 std::string request(http::client &client, http::method method, const std::string &userPath)
 {
     throw socket_exception("curl implementation not enabled");
 }
Beispiel #22
0
                std::string request(http::client &client, http::method method, const std::string &userPath)
                {
                    CURLcode code;

                    char buf[http::MAX_URL_LEN + 1] = {0};

                    struct curl_slist *headers = NULL;

                    CURL *curl = NULL;

                    std::string path = userPath;

                    net::uri uri = client.uri();

                    std::string content = client.content();

                    std::string response;

                    curl = curl_easy_init();

                    if (curl == NULL) {
                        throw socket_exception("unable to initialize curl request");
                    }

                    // check if a path was specified
                    if (path.empty()) {
                        path = uri.full_path();
                    }

                    if (path.empty()) {
                        snprintf(buf, http::MAX_URL_LEN, "%s://%s", uri.scheme().c_str(), uri.host_with_port().c_str());
                    } else if (path[0] == '/') {
                        snprintf(buf, http::MAX_URL_LEN, "%s://%s%s", uri.scheme().c_str(),
                                 uri.host_with_port().c_str(), path.c_str());
                    } else {
                        snprintf(buf, http::MAX_URL_LEN, "%s://%s/%s", uri.scheme().c_str(),
                                 uri.host_with_port().c_str(), path.c_str());
                    }

                    helper::curl_set_opt(curl, CURLOPT_URL, buf);

                    helper::curl_set_opt_fun(curl, CURLOPT_WRITEFUNCTION, helper::curl_append_response_callback);

                    helper::curl_set_opt_num(curl, CURLOPT_HEADER, 1L);

#ifdef DEBUG
                    helper::curl_set_opt_num(curl, CURLOPT_VERBOSE, 1L);
#endif

                    switch (method) {
                        case http::GET:
                            helper::curl_set_opt_num(curl, CURLOPT_HTTPGET, 1L);
                            break;
                        case http::POST:
                            helper::curl_set_opt_num(curl, CURLOPT_POST, 1L);
                            if (!content.empty()) {
                                helper::curl_set_opt(curl, CURLOPT_POSTFIELDS, content.c_str());
                                helper::curl_set_opt_num(curl, CURLOPT_POSTFIELDSIZE, content.size());
                            }
                            break;
                        case http::PUT:
                            helper::curl_set_opt_num(curl, CURLOPT_PUT, 1L);
                            if (!content.empty()) {
                                helper::curl_set_opt(curl, CURLOPT_POSTFIELDS, content.c_str());
                                helper::curl_set_opt_num(curl, CURLOPT_POSTFIELDSIZE, content.size());
                            }
                            break;
                        default:
                            helper::curl_set_opt(curl, CURLOPT_CUSTOMREQUEST, http::method_names[method]);
                            break;
                    }

                    for (auto &h : client.headers()) {
                        snprintf(buf, http::MAX_URL_LEN, "%s: %s", h.first.c_str(), h.second.c_str());
                        headers = curl_slist_append(headers, buf);
                    }

                    helper::curl_set_opt(curl, CURLOPT_HTTPHEADER, headers);

                    helper::curl_set_opt_num(curl, CURLOPT_TIMEOUT, client.timeout());

                    helper::curl_set_opt(curl, CURLOPT_WRITEDATA, &response);

                    CURLcode res = curl_easy_perform(curl);

                    curl_slist_free_all(headers);

                    if (res != CURLE_OK && res != CURLE_PARTIAL_FILE) {
                        curl_easy_cleanup(curl);

                        throw socket_exception(curl_easy_strerror(res));
                    }

                    curl_easy_cleanup(curl);

                    return response;
                }
Beispiel #23
0
                std::string request(http::client &client, http::method method, const string &userPath)
                {
                    char buf[http::MAX_URL_LEN + 1] = {0};

                    buffered_socket sock;

                    std::string path = userPath;

                    net::uri uri = client.uri();

                    std::string content = client.content();

                    if (client.is_secure()) {
                        sock.set_secure(true);
                    }

                    if (!uri.port().empty()) {
                        int port = stoi(uri.port());

                        if (!sock.connect(uri.host(), port)) {
                            throw socket_exception("unable to connect to " + uri.to_string());
                        }
                    } else {
                        if (!sock.connect(uri.host(),
                                          client.is_secure() ? http::DEFAULT_SECURE_PORT : http::DEFAULT_PORT)) {
                            throw socket_exception("unable to connect to " + uri.to_string());
                        }
                    }

                    if (path.empty()) {
                        path = uri.full_path();
                    }

                    // send the method and path

                    if (path.empty())
                        snprintf(buf, http::MAX_URL_LEN, http::REQUEST_PREAMBLE, http::method_names[method], "/",
                                 client.version().c_str());
                    else if (path[0] == '/')
                        snprintf(buf, http::MAX_URL_LEN, http::REQUEST_PREAMBLE, http::method_names[method],
                                 path.c_str(), client.version().c_str());
                    else
                        snprintf(buf, http::MAX_URL_LEN, http::REQUEST_PREAMBLE, http::method_names[method],
                                 ("/" + path).c_str(), client.version().c_str());

                    sock.writeln(buf);

                    bool chunked = client.has_header(http::HEADER_TRANSFER_ENCODING) &&
                                   !strcasecmp(client.header(http::HEADER_TRANSFER_ENCODING).c_str(), "chunked");

                    // specify the host
                    if (!client.has_header(http::HEADER_HOST)) {
                        snprintf(buf, http::MAX_URL_LEN, "%s: %s", http::HEADER_HOST, uri.host().c_str());
                        sock.writeln(buf);
                    }

                    if (!client.has_header(http::HEADER_ACCEPT)) {
                        snprintf(buf, http::MAX_URL_LEN, "%s: */*", http::HEADER_ACCEPT);
                        sock.writeln(buf);
                    }

                    if (!client.has_header(http::HEADER_CONNECTION)) {
                        snprintf(buf, http::MAX_URL_LEN, "%s: close", http::HEADER_CONNECTION);
                        sock.writeln(buf);
                    }

                    // add the headers
                    for (const auto &h : client.headers()) {
                        snprintf(buf, http::MAX_URL_LEN, "%s: %s", h.first.c_str(), h.second.c_str());
                        sock.writeln(buf);
                    }

                    // if we have a content, add the size
                    if (!chunked && !content.empty()) {
                        snprintf(buf, http::MAX_URL_LEN, "%s: %zu", http::HEADER_CONTENT_SIZE, content.size());
                        sock.writeln(buf);
                    }

                    // finish header
                    sock.writeln();

                    // add the content
                    if (!content.empty()) {
                        sock.write(content);
                    }

#ifdef DEBUG
                    cout << string(sock.output().begin(), sock.output().end());
#endif

                    if (!sock.write_from_buffer()) {
                        throw socket_exception("unable to write to socket");
                    }

                    if (!sock.read_to_buffer()) {
                        throw socket_exception("unable to read from socket");
                    }

                    auto input = sock.input();

                    return string(input.begin(), input.end());
                }