Exemple #1
0
Socket::Socket()
: descriptor_(0),
  addr_family_(AF_INET),
  type_(SOCK_STREAM),
  protocol_(0),
  close_on_delete_(true),
  is_alive_(false)
{
    // Create a UDT socket
    descriptor_ = UDT::socket(addr_family_, type_, protocol_);

    // Catch a possible error
    if (descriptor_ == UDT::INVALID_SOCK)
    {
        translateUDTError();
        return;
    }

    PYUDT_LOG_TRACE("Created UDT socket " << descriptor_);

    // Set default socket options
    bool blocking_send = false;
    bool blocking_recv = true;
    if (UDT::ERROR == UDT::setsockopt(descriptor_, 0, UDT_SNDSYN,
                                      &blocking_send, sizeof(blocking_send))
     || UDT::ERROR == UDT::setsockopt(descriptor_, 0, UDT_RCVSYN,
                                      &blocking_recv, sizeof(blocking_recv))
       )
    {
        translateUDTError();
        return;
    }

    PYUDT_LOG_TRACE("Set default options for UDT socket " << descriptor_);
}
Exemple #2
0
Socket::Socket(UDTSOCKET descriptor, bool close_on_delete)
: descriptor_(descriptor),
  addr_family_(0),
  type_(0),
  protocol_(0),
  close_on_delete_(close_on_delete),
  is_alive_(true)
{
    PYUDT_LOG_TRACE("Created Socket object from existing socket " << descriptor_);

    PYUDT_LOG_TRACE("Setting options for UDT socket " << descriptor_);

    // TODO: find a way to get the address family, type and protocol from an
    //       existing UDT socket.
    addr_family_ = AF_INET;
    type_ = SOCK_STREAM;

    // Set default socket options
    bool blocking_send = false;
    bool blocking_recv = true;
    if (UDT::ERROR == UDT::setsockopt(descriptor_, 0, UDT_SNDSYN,
                                      &blocking_send, sizeof(blocking_send))
     || UDT::ERROR == UDT::setsockopt(descriptor_, 0, UDT_RCVSYN,
                                      &blocking_recv, sizeof(blocking_recv))
       )
    {
        translateUDTError();
        return;
    }

    PYUDT_LOG_TRACE("Default options set for UDT socket " << descriptor_);
}
Exemple #3
0
boost::tuple<Socket_ptr, boost::tuple<const char*,uint16_t> >
Socket::accept() throw()
{
    PYUDT_LOG_TRACE("Accepting connection to socket " << descriptor_ << "...");

    // Parameters of the incoming connection
    sockaddr_in client_addr;
    int client_addrlen;
    UDTSOCKET client_descriptor;

    // Retrieve an incoming connection
    Py_BEGIN_ALLOW_THREADS;
    client_descriptor = UDT::accept(descriptor_,
                                    (sockaddr*)&client_addr,
                                    &client_addrlen);
    Py_END_ALLOW_THREADS;

    if (client_descriptor == UDT::ERROR)
    {
        translateUDTError();
        return boost::tuple<Socket_ptr, boost::tuple<const char*,uint16_t> >
               (Socket_ptr(), boost::tuple<const char*,uint16_t>("", 0));
    }

    Socket_ptr client = make_shared<Socket>(client_descriptor);

    client->descriptor_  = client_descriptor;
    client->addr_family_ = addr_family_;
    client->type_        = type_;
    client->protocol_    = protocol_;
    client->is_alive_    = true;

    char client_host[NI_MAXHOST];
    char client_srvc[NI_MAXSERV];

    memset(client_host, '\0', sizeof(client_host));
    memset(client_srvc, '\0', sizeof(client_srvc));

    // Get the client hostname
    if (getnameinfo((sockaddr*) &client_addr, client_addrlen,
                                 client_host, sizeof(client_host) ,
                                 client_srvc, sizeof(client_srvc) ,
                                 NI_NUMERICHOST | NI_NUMERICSERV))
    {
        PYUDT_LOG_ERROR("Failed to get the client host info");
    }


    PYUDT_LOG_TRACE("Accepted connection to socket " << descriptor_
                    << " from address " << client_host);

    return boost::tuple<Socket_ptr, boost::tuple<const char*, uint16_t> >
           (make_shared<Socket>(client->getDescriptor()),
            boost::tuple<const char*, uint16_t>
            (client_host, client_addr.sin_port));
}
Exemple #4
0
Epoll::~Epoll()
{
    PYUDT_LOG_TRACE("Releasing epoll " << id_ << "...");

    // Release the epoll
    if (UDT::epoll_release(id_) < 0)
    {
        PYUDT_LOG_ERROR("Could not release epoll " << id_);
        translateUDTError();
        return;
    }

    PYUDT_LOG_TRACE("Released epoll " << id_);
}
Exemple #5
0
void Epoll::garbage_collect() throw()
{
    std::map<UDTSOCKET, Socket*>::iterator iter;
    UDTSTATUS status;

    for (iter = objmap_.begin();
         iter != objmap_.end();
         ++iter)
    {
        status = UDT::getsockstate(iter->first);
        if (  status == BROKEN
           || status == CLOSED
           || status == NONEXIST)
        {
            // Remove the UDT socket from the epoll
            UDT::epoll_remove_usock(id_, iter->first);

            // Destroy the socket
            delete iter->second;

            // Remove the socket from the map
            objmap_.erase(iter);
        }
    }

    PYUDT_LOG_TRACE("Garbage collection done for epoll " << id_);
}
Exemple #6
0
py::str Socket::recv(int buf_len) const throw()
{
    int res;
    char* buf = (char*) malloc (buf_len * sizeof(char));

    // Initialize the buffer to \0
    memset(buf, '\0', buf_len);

    // FIXME: useful python macros?
    Py_BEGIN_ALLOW_THREADS;
    res = UDT::recv(descriptor_, buf, buf_len, 0);
    Py_END_ALLOW_THREADS;

    if (res == UDT::ERROR)
    {
        free(buf);
        PYUDT_LOG_ERROR("Could not receive data from socket " << descriptor_);
        translateUDTError();

        // None
        return py::str();
    }

    py::str py_buf = buf;
    free(buf);

    PYUDT_LOG_TRACE("Received " << buf_len << " byte(s) from socket "
                    << descriptor_ << " that are stored in "
                    << static_cast<void *>(&buf));

    return py_buf;
}
Exemple #7
0
void Socket::send(const char* buf, int buf_len) const throw()
{
    if (buf == nullptr)
    {
        throw Exception("Null buffer provided during Socket::send", "");
    }

    int res;

    // FIXME: useful python macros?
    Py_BEGIN_ALLOW_THREADS;
    res = UDT::send(descriptor_, buf, buf_len, 0);
    Py_END_ALLOW_THREADS;

    if (res == UDT::ERROR)
    {
        PYUDT_LOG_ERROR("Could not send data through socket " << descriptor_);
        translateUDTError();
        return;
    }

    PYUDT_LOG_TRACE("Sent " << buf_len << " byte(s) through socket "
                    << descriptor_ << " that were stored in "
                    << static_cast<void *>(&buf));
}
Exemple #8
0
void Socket::close()
{
    int res;

    if (is_alive_)
    {
        res = UDT::close(descriptor_);

        // FIXME: currently ignore invalid socket errors
        // This happens when the socket destructor is called after the epoll
        // destructor.
        if (res == UDT::ERROR
            && UDT::getlasterror().getErrorCode() != CUDTException::EINVSOCK)
        {
            translateUDTError();
            return;
        }
        else
        {
            PYUDT_LOG_TRACE("Closed UDT socket " << descriptor_);
        }

        is_alive_ = false;
    }
}
Exemple #9
0
void Socket::recv(char* buf, int buf_len) const throw()
{
    if (buf == nullptr)
    {
        throw Exception("Null buffer provided during Socket::recv", "");
    }

    int res;

    // Initialize the buffer to \0
    memset(buf, '\0', buf_len);

    // FIXME: useful python macros?
    Py_BEGIN_ALLOW_THREADS;
    res = UDT::recv(descriptor_, buf, buf_len, 0);
    Py_END_ALLOW_THREADS;

    if (res == UDT::ERROR)
    {
        PYUDT_LOG_ERROR("Could not receive data from socket " << descriptor_);
        translateUDTError();
        return;
    }

    PYUDT_LOG_TRACE("Received " << buf_len << " byte(s) from socket "
                    << descriptor_ << " that are stored in "
                    << static_cast<void *>(&buf));
}
Exemple #10
0
Epoll::Epoll()
{
    PYUDT_LOG_TRACE("Creating an epoll...");

    // Create the epoll
    id_ = UDT::epoll_create();

    // Catch a possible error
    if (id_ < 0)
    {
        PYUDT_LOG_ERROR("Could not create an epoll");
        translateUDTError();
        return;
    }

    PYUDT_LOG_TRACE("Created epoll " << id_);
}
Exemple #11
0
Socket::~Socket()
{
    // TODO: make sure that the socket is no longer referenced in an epoll

    // Close socket on destruction
    if (close_on_delete_) close();

    PYUDT_LOG_TRACE("Destroyed UDT socket " << descriptor_);
}
Exemple #12
0
void Socket::listen(unsigned int backlog) throw()
{
    if (UDT::ERROR == UDT::listen(descriptor_, backlog))
    {
        translateUDTError();
        return;
    }

    PYUDT_LOG_TRACE("Socket " << descriptor_
                    << " set to listen state. Maximum number of pending "
                    << "connections = " << backlog);
}
Exemple #13
0
void Socket::bind_to_udp(UDPSOCKET udp_socket) throw()
{
    if (UDT::ERROR == UDT::bind2(descriptor_, udp_socket))
    {
        translateUDTError();
        return;
    }

    is_alive_ = true;
    PYUDT_LOG_TRACE("Bound UDT socket " << descriptor_
                    << " to UDP socket " << udp_socket);
}
Exemple #14
0
void Socket::send(py::object py_buf) const throw()
{
    // pointer to buffer
    char* buf = nullptr;
    // true buffer length
    int buf_len = 0;
    // passed in length size
    int pref_len = 0;

    // TODO: find a way to use Boost.Python instead
    if (!PyArg_ParseTuple(py_buf.ptr(), "s#ii", &buf, &buf_len, &pref_len))
    {
        Exception e("Wrong arguments: Socket::send((char*)buf, (int)buf_len)", "");
        translateException(e);
        throw e;
    }
    else
    {
        if ((pref_len - buf_len) > buf_len)
        {
            Exception e("Buffer length must not double real buffer length", "");
            translateException(e);
            throw e;

            return;
        }
    }

    if (buf == nullptr)
    {
        Exception e("Null buffer provided during Socket::send", "");
        translateException(e);
        throw e;
    }

    int res;

    // FIXME: useful python macros?
    Py_BEGIN_ALLOW_THREADS;
    res = UDT::send(descriptor_, buf, buf_len, 0);
    Py_END_ALLOW_THREADS;

    if (res == UDT::ERROR)
    {
        PYUDT_LOG_ERROR("Could not send data through socket " << descriptor_);
        translateUDTError();
        return;
    }

    PYUDT_LOG_TRACE("Sent " << buf_len << " byte(s) through socket "
                    << descriptor_ << " that were stored in "
                    << static_cast<void *>(&buf));
}
Exemple #15
0
void Socket::connect(const char* ip, uint16_t port) throw()
{
    sockaddr_in addr = build_sockaddr_in(ip, port);

    if (UDT::ERROR == UDT::connect(descriptor_, (sockaddr*) &addr, sizeof(addr)))
    {
        translateUDTError();
        return;
    }

    is_alive_ = true;
    PYUDT_LOG_TRACE("Connect socket " << descriptor_ << " to address "
                    << ip << ":" << port);
}
Exemple #16
0
void Epoll::add_ssock(py::object py_socket, py::object py_flags) throw()
{
    // File descriptor of a system socket
    SYSSOCKET socket;
    int flags;

    try
    {
        // Extract the flags
        flags = py::extract<int>(py_flags);

        // First, try to extract a file descriptor
        py::extract<SYSSOCKET> get_syssocket(py_socket);
        if (get_syssocket.check()) socket = get_syssocket();
        else
        {
            // Second, try to treat this as a Python TCP socket
            try
            {
                socket = py::call_method<SYSSOCKET>(py_socket.ptr(), "fileno");
            }
            catch (...)
            {
                Exception e("Wrong arguments: Epoll::add_ssock((SYSSOCKET)s, "\
                            "(int)flags)", "");
                translateException(e);
                throw e;
            }
        }

        if (UDT::ERROR == UDT::epoll_add_ssock(id_, socket, &flags))
        {
            PYUDT_LOG_ERROR("Could not add system socket "
                            << socket << " to epoll " << id_);

            translateUDTError();
            return;
        }
    }
    catch (py::error_already_set& err)
    {
        std::cerr << parse_python_exception() << std::endl;
        throw err;
    }

    PYUDT_LOG_TRACE("Added system socket "
                    << socket
                    << " to epoll " << id_);
}
Exemple #17
0
void Epoll::add_usock(py::object py_socket, py::object py_flags) throw()
{
    Socket* socket;
    int flags;

    try
    {
        try
        {
            socket = py::extract<Socket*>(py_socket);
            flags = py::extract<int>(py_flags);
        }
        catch (...)
        {
            Exception e("Wrong arguments: Epoll::add_usock((Socket)s, (int)flags)", "");
            translateException(e);
            throw e;
        }

        objmap_[socket->getDescriptor()] = socket;

        if (UDT::ERROR == UDT::epoll_add_usock(id_, socket->getDescriptor(), &flags))
        {
            PYUDT_LOG_ERROR("Could not add UDT socket "
                            << socket->getDescriptor()
                            << " to epoll " << id_);

            translateUDTError();
            return;
        }
    }
    catch (py::error_already_set& err)
    {
        std::cerr << parse_python_exception() << std::endl;
        throw err;
    }

    PYUDT_LOG_TRACE("Added UDT socket "
                    << socket->getDescriptor()
                    << " to epoll " << id_
                    << " with flag " << flags);
}
Exemple #18
0
void Epoll::remove_ssock(py::object py_socket) throw()
{
    SYSSOCKET socket;

    try
    {
        py::extract<SYSSOCKET> get_syssocket(py_socket);
        if (get_syssocket.check()) socket = get_syssocket();
        else
        {
            try
            {
                socket = py::call_method<SYSSOCKET>(py_socket.ptr(), "fileno");
            }
            catch (...)
            {
                Exception e("Wrong arguments: Epoll::remove_ssock((SYSSOCKET)s)", "");
                translateException(e);
                throw e;
            }
        }

        if (UDT::ERROR == UDT::epoll_remove_ssock(id_, socket))
        {
            PYUDT_LOG_ERROR("Could not remove system socket "
                            << socket << " from epoll " << id_);

            translateUDTError();
            return;
        }
    }
    catch (py::error_already_set& err)
    {
        std::cerr << parse_python_exception() << std::endl;
        throw err;
    }

    PYUDT_LOG_TRACE("Removed system socket "
                    << socket
                    << " from epoll " << id_);
}
Exemple #19
0
void Epoll::add_ssock(py::object py_socket, py::object py_flags) throw()
{
    // file descriptor of a system socket
    SYSSOCKET socket;
    int flags;

    try
    {
        try
        {
            socket = py::extract<SYSSOCKET>(py_socket);
            flags = py::extract<int>(py_flags);
        }
        catch (...)
        {
            Exception e("Wrong arguments: Epoll::add_ssock((SYSSOCKET)s, (int)flags)", "");
            translateException(e);
            throw e;
        }

        if (UDT::ERROR == UDT::epoll_add_ssock(id_, socket, &flags))
        {
            PYUDT_LOG_ERROR("Could not add system socket "
                            << socket << " to epoll " << id_);

            translateUDTError();
            return;
        }
    }
    catch (py::error_already_set& err)
    {
        std::cerr << parse_python_exception() << std::endl;
        throw err;
    }

    PYUDT_LOG_TRACE("Added system socket "
                    << socket
                    << " to epoll " << id_);
}
Exemple #20
0
void Epoll::remove_usock(py::object py_socket) throw()
{
    Socket* socket;

    try
    {
        try
        {
            socket = py::extract<Socket*>(py_socket);
        }
        catch (...)
        {
            Exception e("Wrong arguments: Epoll::remove_usock((Socket)s)", "");
            translateException(e);
            throw e;
        }

        objmap_.erase(socket->getDescriptor());

        if (UDT::ERROR == UDT::epoll_remove_usock(id_, socket->getDescriptor()))
        {
            PYUDT_LOG_ERROR("Could not remove UDT socket "
                            << socket->getDescriptor()
                            << " from epoll " << id_);

            translateUDTError();
            return;
        }
    }
    catch (py::error_already_set& err)
    {
        std::cerr << parse_python_exception() << std::endl;
        throw err;
    }

    PYUDT_LOG_TRACE("Removed UDT socket "
                    << socket->getDescriptor()
                    << " from epoll " << id_);
}
Exemple #21
0
int Epoll::wait(int64_t ms_timeout,
                bool do_uread, bool do_uwrite,
                bool do_sread, bool do_swrite) throw ()
{
    int res = UDT::epoll_wait(id_,
                             (do_uread)? &read_udt_:nullptr,
                             (do_uwrite)? &write_udt_:nullptr,
                             ms_timeout,
                             (do_sread)? &read_sys_:nullptr,
                             (do_swrite)? &write_sys_:nullptr);

    if (res == UDT::ERROR)
    {
        if (UDT::getlasterror().getErrorCode() == CUDTException::ETIMEOUT)
            res = 0;
        else translateUDTError();
    }

    PYUDT_LOG_TRACE("Number of UDT/system sockets ready for IO in epoll "
                    << id_ << ": " << res);

    return res;
}