コード例 #1
0
static bool
DecodeHostAndPort (const char *host_and_port, 
                   std::string &host_str, 
                   std::string &port_str, 
                   int32_t& port,
                   Error *error_ptr)
{
    RegularExpression regex ("([^:]+):([0-9]+)");
    if (regex.Execute (host_and_port, 2))
    {
        if (regex.GetMatchAtIndex (host_and_port, 1, host_str) &&
            regex.GetMatchAtIndex (host_and_port, 2, port_str))
        {
            port = Args::StringToSInt32 (port_str.c_str(), INT32_MIN);
            if (port != INT32_MIN)
            {
                if (error_ptr)
                    error_ptr->Clear();
                return true;
            }
        }
    }
    host_str.clear();
    port_str.clear();
    port = INT32_MIN;
    if (error_ptr)
        error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port);
    return false;
}
コード例 #2
0
ConnectionStatus
ConnectionFileDescriptor::SocketConnect (const char *host_and_port, Error *error_ptr)
{
    lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION,
                                 "%p ConnectionFileDescriptor::SocketConnect (host/port = %s)",
                                 this, host_and_port);
    Close (m_fd, false);
    m_is_socket = true;

    RegularExpression regex ("([^:]+):([0-9]+)");
    if (regex.Execute (host_and_port, 2) == false)
    {
        if (error_ptr)
            error_ptr->SetErrorStringWithFormat("Invalid host:port specification: '%s'.\n", host_and_port);
        return eConnectionStatusError;
    }
    std::string host_str;
    std::string port_str;
    if (regex.GetMatchAtIndex (host_and_port, 1, host_str) == false ||
        regex.GetMatchAtIndex (host_and_port, 2, port_str) == false)
    {
        if (error_ptr)
            error_ptr->SetErrorStringWithFormat("Invalid host:port specification '%s'.\n", host_and_port);
        return eConnectionStatusError;
    }

    int32_t port = Args::StringToSInt32 (port_str.c_str(), INT32_MIN);
    if (port == INT32_MIN)
    {
        if (error_ptr)
            error_ptr->SetErrorStringWithFormat("Invalid port '%s'.\n", port_str.c_str());
        return eConnectionStatusError;
    }
    // Create the socket
    m_fd = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (m_fd == -1)
    {
        if (error_ptr)
            error_ptr->SetErrorToErrno();
        return eConnectionStatusError;
    }

    m_should_close_fd = true;

    // Enable local address reuse
    SetSocketOption (m_fd, SOL_SOCKET, SO_REUSEADDR, 1);

    struct sockaddr_in sa;
    ::bzero (&sa, sizeof (sa));
    sa.sin_family = AF_INET;
    sa.sin_port = htons (port);

    int inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr);

    if (inet_pton_result <= 0)
    {
        struct hostent *host_entry = gethostbyname (host_str.c_str());
        if (host_entry)
            host_str = ::inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list);
        inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr);
        if (inet_pton_result <= 0)
        {

            if (error_ptr)
            {
                if (inet_pton_result == -1)
                    error_ptr->SetErrorToErrno();
                else
                    error_ptr->SetErrorStringWithFormat("Invalid host string: '%s'.\n", host_str.c_str());
            }
            Close (m_fd, false);
            return eConnectionStatusError;
        }
    }

    if (-1 == ::connect (m_fd, (const struct sockaddr *)&sa, sizeof(sa)))
    {
        if (error_ptr)
            error_ptr->SetErrorToErrno();
        Close (m_fd, false);
        return eConnectionStatusError;
    }

    // Keep our TCP packets coming without any delays.
    SetSocketOption (m_fd, IPPROTO_TCP, TCP_NODELAY, 1);
    if (error_ptr)
        error_ptr->Clear();
    return eConnectionStatusSuccess;
}