Ejemplo n.º 1
0
int
SocketBase::doSend(const void* data, size_t len)
{
    if ( state == CONNECTED )
    {
        int res = send(sockfd, (const char*) data, len, SEND_FLAGS);
        if(res == SOCKET_ERROR) {
            lastError = GET_NET_ERROR();
            if ( IS_IGNORABLE_ERROR(lastError) )
                return 0;

            if ( ! IS_DISCONECTED(lastError) ) {
                std::stringstream msg;
                msg << "Send error: " << NETSTRERROR(lastError);
                LOGGER.warning("%s", msg.str().c_str());
            }

            onDisconected();
            return 0;
        }
        return res;
    }
    else
    {
        LOGGER.warning("Trying to send to unconected socket [%s]", getStateString());
    }
    return 0;
}
Ejemplo n.º 2
0
void
SocketBase::setNonBlocking() throw(NetworkException)
{
    if ( state >= CREATED )
    {
        int res;
#ifdef _WIN32
        unsigned long mode = 1;
        res = ioctlsocket(sockfd, FIONBIO, &mode);
#else
        res = fcntl(sockfd, F_SETFL, O_NONBLOCK);
#endif
        if ( res == SOCKET_ERROR ) {
            lastError = GET_NET_ERROR();
    //        doClose();
            std::stringstream msg;
            msg << "Couldn't set socket to nonblocking mode: " << NETSTRERROR(lastError);
            LOGGER.warning("%s", msg.str().c_str());
        }
    }
    else
    {
        LOGGER.warning("Trying to configure uncreated socket [%s]", getStateString());
    }
}
Ejemplo n.º 3
0
void
SocketBase::doConnect() throw(NetworkException)
{
    if ( state == CONFIGURED )
    {
        int res = connect(sockfd, addr.getSockaddr(), addr.getSockaddrLen());
        if(res == SOCKET_ERROR)
        {
            lastError = GET_NET_ERROR();
            if ( !IS_CONNECT_INPROGRESS(lastError) )
            {
                doClose();
                std::stringstream msg;
                msg << "Couldn't connect to '" << addr.getIP() << "' port "
                    << addr.getPort() << ": " << NETSTRERROR(lastError);
                throw NetworkException(msg.str());
            }
        }
        state = CONNECTING;
        disconnectTimer.reset();
        SocketManager::addSocket(this);
    }
    else
    {
        LOGGER.warning("Trying to connect to an unconfigured socket [%s]", getStateString());
    }
}
Ejemplo n.º 4
0
int
SocketBase::doSendTo(const Address& toaddr, const void* data, size_t len) throw(NetworkException)
{
    if ( state == BOUND )
    {
        int res = sendto(sockfd, (const char*) data, len, SEND_FLAGS,
                    toaddr.getSockaddr(), toaddr.getSockaddrLen());
        if(res == SOCKET_ERROR) {
            lastError = GET_NET_ERROR();
            if ( ! IS_SENDTO_IGNORABLE(lastError) )
            {
                std::stringstream msg;
                msg << "Send error: " << NETSTRERROR(lastError);
                LOGGER.warning("%s", msg.str().c_str());
            }
            return 0;
        }
        return res;
    }
    else
    {
        LOGGER.warning("Trying to sendto in an unbound socket [%s]", getStateString());
    }
    return 0;
}
Ejemplo n.º 5
0
size_t
SocketBase::doReceiveFrom(Address& fromaddr, void* buffer, size_t len) throw(NetworkException)
{
    if ( state == BOUND || state == CONNECTED )
    {
        int res = recvfrom(sockfd, (char*) buffer, len, RECV_FLAGS,
                fromaddr.getSockaddr(), fromaddr.getSockaddrLenPointer());
        if ( res == SOCKET_ERROR )
        {
            lastError = GET_NET_ERROR();
            if ( ! IS_RECVFROM_IGNORABLE(lastError) )
            {
                std::stringstream msg;
                msg << "ReceiveFrom error: " << NETSTRERROR(lastError);
                LOGGER.warning("%s", msg.str().c_str());
            }

            return 0;
        }
        return res;
    }
    else
    {
        LOGGER.warning("Trying to receivefrom on an not bound or conected socket [%s]", getStateString());
    }
    return 0;
}
Ejemplo n.º 6
0
int
NSocketX::sysSend(const char *b, unsigned int s, const struct sockaddr_storage *to_ssaddr, int tolen)
{
    if (s < 1)
    {
        return s; // XXX WE SHOULD LAUNCH onSoftwareError();
    }
    
    if (to_ssaddr)
    { // MUST BE A UDP
        sys_result = sendto(fd,b,s,0,(const struct sockaddr *)to_ssaddr,tolen);
    }
    else
    {
        sys_result = send(fd,b,s,0);
    }
    
    if (sys_result == SOCKET_ERROR)
    {
        error=GET_NET_ERROR();
        printf("[%d] sysSend Error: %s\n", fd, strerror(error));
        listener->onSocketError(this); //onSendError(); // XXX check for errors
        return -1;
    }
    return sys_result;
}
Ejemplo n.º 7
0
SOCKET
SocketBase::doAccept(Address& fromaddr) throw(NetworkException)
{
    if ( state == LISTENING )
    {
        SOCKET newsock;
        newsock= accept(sockfd, fromaddr.getSockaddr(), fromaddr.getSockaddrLenPointer());
        if ( newsock == INVALID_SOCKET )
        {
            lastError = GET_NET_ERROR();
            if ( ! IS_ACCEPT_IGNORABLE(lastError) )
            {
                std::stringstream msg;
                msg << "Accept error: " << NETSTRERROR(lastError);
                LOGGER.warning("%s", msg.str().c_str());
            }
        }
        return newsock;
    }
    else
    {
        LOGGER.warning("Trying to accept on an unlistening socket [%s]", getStateString());
    }
    return SOCKET_ERROR;
}
Ejemplo n.º 8
0
int
SocketBase::doReceive(void* buffer, size_t len) throw(NetworkException)
{
    if ( state == CONNECTED )
    {
        int res = recv(sockfd, (char*) buffer, len, RECV_FLAGS);
        if(res == SOCKET_ERROR) {
            lastError = GET_NET_ERROR();
            if ( IS_IGNORABLE_ERROR(lastError) )
                return 0;

            if ( ! IS_DISCONECTED(lastError) ) {
                std::stringstream msg;
                msg << "Read error: " << NETSTRERROR(lastError);
                LOGGER.warning("%s", msg.str().c_str());
            }

            onDisconected();
            return 0;
        }

        if (!res) {
            LOGGER.debug("SocketBase::doReceive Disconected from server");
            onDisconected();
        }

        return res;
    }
    else
    {
        LOGGER.warning("Trying to receive on unconected socket [%s]", getStateString());
    }
    return 0;
}
Ejemplo n.º 9
0
/*
 * sysAccept
 */
void
NSocketX::sysAccept()
{
    char new_ipaddress[NI_MAXHOST];
    char new_port[NI_MAXSERV];
    NSocket * newcon;
    SOCKET new_fd;
    sockaddr_storage new_ssaddr;
    socklen_t slen = sizeof(new_ssaddr);

    new_fd = accept(fd,(struct sockaddr *) &new_ssaddr, &slen);
    if ( new_fd == INVALID_SOCKET )
    {
        error=GET_NET_ERROR();
        switch (error)
        {
        // Notify on BAD errors, the rest are ignorable
        // Note that this errors are NSocket errors
#ifdef _WIN32
            // for windows
            case WSAENOTSOCK:
            case WSAEOPNOTSUPP:
            case WSAEINVAL:
            case WSAEFAULT:
            case WSANOTINITIALISED:
#else
            // for others
            case EBADF:
            case ENOTSOCK:
            case EOPNOTSUPP:
            case EINVAL: // not in macosx, should test if this compiles in it
            case EFAULT:
#endif
                notifyError(); // on this errors this socket should be closed
        }
        return; // nothing more to do
    }

    sockaddr_to_ip(&new_ssaddr,slen,new_ipaddress,new_port);

    newcon=onNewConnection(new_ipaddress, new_port);
    if (newcon)
    {
        newcon->fd = new_fd;
        newcon->has_socket = true;
        strcpy(newcon->ipaddress, new_ipaddress);
        strcpy(newcon->port, new_port);
        //NSocketManager::add_to_list(newcon);
        newcon->onSocketReady();
    }
    else
    {
        closesocket(new_fd);
    }
}
Ejemplo n.º 10
0
bool
NSocketX::setReuseAddr()
{
    int v=1;
    sys_result = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, SETSOCKOPT_TYPE &v, sizeof(v));
    if (sys_result == SOCKET_ERROR)
    {
        error=GET_NET_ERROR();
        notifyError();
    }
    return true;
}
Ejemplo n.º 11
0
    /** Waits for input on the sockets in the set until a socket has input or a
     * timeout occurs. Returns false in case of timeout.
     */
    int select(unsigned int timeout_usec = 0)
    {
        if ( !readset_ptr && !writeset_ptr )
            return 0;

        timeout.tv_sec = timeout_usec/1000000;
        timeout.tv_usec = timeout_usec%1000000;
        
        int res = ::select(maxfd+1, readset_ptr, writeset_ptr, 0, &timeout);
        if ( res == SOCKET_ERROR ) {
            select_error = GET_NET_ERROR();
            return -1;
        }

        return res;
    }
Ejemplo n.º 12
0
bool
NSocketX::setNonBlock()
{
#ifdef _WIN32
    unsigned long mode = 1;
    sys_result = ioctlsocket(fd, FIONBIO, &mode);
#else
    sys_result = fcntl(fd, F_SETFL, O_NONBLOCK);
#endif
    if (sys_result == SOCKET_ERROR)
    {
        error=GET_NET_ERROR();
        notifyError();
    }
    return true;
}
Ejemplo n.º 13
0
void
SocketBase::doListen() throw(NetworkException)
{
    if ( state == BOUND )
    {
        int res = listen(sockfd, 20);
        if(res == SOCKET_ERROR) {
            lastError = GET_NET_ERROR();
            doClose();
            std::stringstream msg;
            msg << "Couldn't listen on socket: " << NETSTRERROR(lastError);
            throw NetworkException(msg.str());
        }
        state = LISTENING;
    }
    else
    {
        LOGGER.warning("Trying to listen on an unbound socket [%s]", getStateString());
    }
}
Ejemplo n.º 14
0
void
SocketBase::setNoDelay() throw(NetworkException)
{
    if ( state >= CONFIGURED )
    {
        SETSOCKOPT_PARAMTYPE val = 1;
        int res = setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
        if(res == SOCKET_ERROR) {
            lastError = GET_NET_ERROR();
    //        doClose();
            std::stringstream msg;
            msg << "Couldn't set TCP_NODELAY: " << NETSTRERROR(lastError);
            LOGGER.warning("%s", msg.str().c_str());
        }
    }
    else
    {
        LOGGER.warning("Trying to set nodelay on an unconfigured socket [%s]", getStateString());
    }
}
Ejemplo n.º 15
0
void
SocketBase::setReuseAddr() throw(NetworkException)
{
    if ( state == CONFIGURED )
    {
        SETSOCKOPT_PARAMTYPE val = 1;
        int res = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
        if(res == SOCKET_ERROR) {
            lastError = GET_NET_ERROR();
    //        doClose();
            std::stringstream msg;
            msg << "Couldn't set SO_REUSEADDR: " << NETSTRERROR(lastError);
            LOGGER.warning("%s", msg.str().c_str());
        }
    }
    else
    {
        LOGGER.warning("Trying to set reuse addr on an unconfigured socket [%s]", getStateString());
    }
}
Ejemplo n.º 16
0
void
SocketBase::create () throw(NetworkException)
{
    if ( state == RESOLVED )
    {
        sockfd = socket(PF_INET, addr.socktype, addr.protocol);

        LOGGER.debug("SocketBase:: Create [%s:%d] socket", (addr.socktype == SOCK_STREAM)?"tcp":"udp",sockfd);

        if(sockfd == INVALID_SOCKET)
        {
            lastError = GET_NET_ERROR();
            std::stringstream msg;
            msg << "Couldn't create socket: " << NETSTRERROR(lastError);
            throw NetworkException(msg.str());
        }
        state = CREATED;
    }
    else
    {
        LOGGER.warning("Trying to recreate a socket [%s]", getStateString());
    }
}
Ejemplo n.º 17
0
void
SocketBase::bindSocketTo(const Address& toaddr) throw(NetworkException)
{
    if ( state == CONFIGURED )
    {
        int res = bind(sockfd, toaddr.getSockaddr(), toaddr.getSockaddrLen());
        if(res == SOCKET_ERROR) {
            lastError = GET_NET_ERROR();
            doClose();
            std::stringstream msg;
            msg << "Couldn't bind socket to address '"
                << toaddr.getIP() << "' port " << toaddr.getPort()
                << ": " << NETSTRERROR(lastError);
            throw NetworkException(msg.str());
        }
        SocketManager::addSocket(this);
        state = BOUND;
    }
    else
    {
        LOGGER.warning("Trying to bind to a socket != CONFIGURED [%s]", getStateString());
    }
}
Ejemplo n.º 18
0
bool
NSocketX::sysRecv()
{
    int read_retrycount = 3; // +1 (first time)
read_again:
    if (from_ssaddr)
    { // this must be a udp socket
        fromlen=sizeof(from_ssaddr);
        sys_result = recvfrom(fd,recvbuffer,NSBUFLEN,0,(struct sockaddr *) from_ssaddr,&fromlen);
    }
    else
    {
        sys_result = recv(fd,recvbuffer,NSBUFLEN,0);
    }
    if (sys_result == SOCKET_ERROR)
    {
        error=GET_NET_ERROR();
        switch (error)
        {
            case NET_ERROR_EINTR:
                if (read_retrycount--)
                    goto read_again;
            case NET_ERROR_EAGAIN:
                return true;
            case NET_ERROR_ENOTCONN:
//                onInternalError("recv: Tryed to receive on an unconected socket (and should be connected)");
//                break;
            case NET_ERROR_ENOTSOCK:
//                onInternalError("recv: The socket is not a socket");
//                break;
            case NET_ERROR_EFAULT:
//                onInternalError("recv: The internal buffer pointer is out of range");
//                break;
            case NET_ERROR_EINVAL:
//                onInternalError("recv: Invalid parameters passed");
//                break;
            case NET_ERROR_ECONNREFUSED:
//                onConnectError();
                sysClose();
                break;
            default:
                printf("[%d] Receive error %s\n", fd, strerror(error));
                listener->onSocketError(this); // XXX receive error
        }
        return false;
    }
    if (sys_result == 0)
    {
        onDisconnected();
        return false;
    }
    if (!onDataReceived(recvbuffer, sys_result))
    {
        disconnect();
        return false;
    }
    else
    {
        return true;
    }
//    return true;
}
Ejemplo n.º 19
0
/****************************************************************************
*
* for support of ipv6: linux, mac osx, windows (xp+, dont compile in older)
*   getaddrinfo, freeaddrinfo, getnameinfo
*
* if we dont want ipv6 support we can do 2 things:
*   1- write our own get/freeaddrinfo and getnameinfo
*   2- use totally different code with gethostbyname, etc...
*
*
* what we will do is, on non windows, use the ipv6_able functions
* and on windows, if the user wants ipv6 support will need to define some
* variable (like _ENABLE_IPV6?) or will only be able to use ipv4 and we will
* use old functions (gethostbyname, inet_addr, ...)
*
* XXX TODO think a way to do asyn DNS
*
****************************************************************************/
void
NSocketX::sysResolve(const char *hostname, const char *p, SOCKET_FLAGS stype)
{
#ifndef _WIN32
    struct addrinfo hints;
    struct addrinfo *address;
    struct addrinfo *firstaddress;

    memset(&hints, 0, sizeof(hints));
    //hints.ai_family = AF_UNSPEC;
    hints.ai_family = AF_INET;
    
    hints.ai_socktype = (stype&TCP) ? SOCK_STREAM : SOCK_DGRAM;
    hints.ai_flags = (stype&LISTEN) ? AI_PASSIVE : 0;

    sys_result = getaddrinfo(hostname, p, &hints, &firstaddress);
    if (sys_result)
    {
        error=sys_result; // this is correct. DON'T CHANGE
        if (error == NET_ERROR_NONAME)
        {
//            onHostNotFoundError();
        }
        return; // XXX check for getaddrinfo errors
    }

    for (address=firstaddress; address; address=address->ai_next)
    {
        fd = socket(address->ai_family, address->ai_socktype, address->ai_protocol);
        if (fd == INVALID_SOCKET)
        {
            error=GET_NET_ERROR();
            continue; // use next address if cant create socket.
        }

        has_socket=true;

        if (!setNonBlock())
        {
            sysClose();
            break; // XXX just close? no error?
        }

        if ( ! (stype & LISTEN) )
        {
            sys_result = connect(fd, address->ai_addr, address->ai_addrlen);
            if (sys_result == SOCKET_ERROR)
            {
                error=GET_NET_ERROR();
                if (error != NET_ERROR_CONINPROGRESS)
                {
                    sysClose();
                    //onConnectError();
                    continue; // try next address if cant connect
                }
                is_connecting=true;
                //add_to_list(this);
                break;
            }
            //add_to_list(this); // XXX may add an element when we are in the loop
            break; // finished the loop here
        }
        else
        { // wants to bind
            if (!setReuseAddr())
            {
                sysClose();
                break; // XXX what can we do?
            }

            sys_result = bind(fd, address->ai_addr, address->ai_addrlen);
            if (sys_result == SOCKET_ERROR)
            {
                error=GET_NET_ERROR();
                sysClose();
                //onBindError();
                break; // XXX what can we do?
            }

            if (stype & TCP)
            {
                sys_result = listen(fd, 10);
                if (sys_result == SOCKET_ERROR)
                {
                    error=GET_NET_ERROR();
                    sysClose();
                    //onListenError();
                    break; // XXX what can we do?
                }
                //add_to_list(this); // XXX should put some onListening()?
            }
            break;
        }
    }

    if (!has_socket)
    {
        printf("dont has socket %d\n", sys_result);
        freeaddrinfo(firstaddress);
        return; // XXX put some errors somewhere, but we already has, dont we?
    }

    socket_type=stype;

    // convert sockaddr to ipaddress and port char *

    memset(ipaddress, 0, NI_MAXHOST);
    memset(port, 0, NI_MAXSERV);
    sys_result = getnameinfo((const sockaddr *) address->ai_addr,
                 address->ai_addrlen,
                 ipaddress, NI_MAXHOST,
                 port, NI_MAXSERV,
                 NI_NUMERICHOST|NI_NUMERICSERV);

    if (sys_result)
    { // XXX maybe check for some errors?
        int hlen;
        hlen=strlen(hostname);
        memcpy(ipaddress,hostname,(hlen<NI_MAXHOST)?hlen:NI_MAXHOST-1);
        hlen=strlen(p);
        memcpy(port,p,(hlen<NI_MAXSERV)?hlen:NI_MAXSERV-1);
    }
    freeaddrinfo(firstaddress); // XXX maybe here maybe up and copy sockaddr_in?
    if ( !(stype & LISTEN) && !is_connecting ) // if we are here is because we are connected
    {
        onSocketReady();
    }
#else
// for windows, no resolver
    struct sockaddr_in sa;
    sa.sin_addr.s_addr=inet_addr(hostname);
    if ( sa.sin_addr.s_addr == 0xffffffff)
    {
      printf("bad name\n");
      return;
    }

    sa.sin_port=htons(53);
    if (!sa.sin_port)
    {
      printf("bad port\n");
      return;
    }

    sa.sin_family=AF_INET;

    int socktype;
    if (stype == TCP || stype == LISTEN_TCP)
    {
        socktype = SOCK_STREAM;
    }
    else
    {
        socktype = SOCK_DGRAM;
    }

    fd = socket(AF_INET, socktype, 0);
    if ( fd == INVALID_SOCKET )
    {
        printf("invalid socket\n");
        return;
    }

    has_socket=true;

    if (!setNonBlock())
    {
        sysClose();
        return; // XXX just close? no error?
    }

    if (stype == TCP || stype == UDP)
    {
        sys_result = connect(fd, (const sockaddr *)&sa, sizeof(sa));
        if (sys_result == SOCKET_ERROR)
        {
            error=GET_NET_ERROR();
            if (error != NET_ERROR_CONINPROGRESS)
            {
                sysClose();
                onConnectError();
                return; // try next address if cant connect
            }
            is_connecting=true;
            NSocketManager::add_to_list(this);
            return;
        }
        NSocketManager::add_to_list(this); // XXX may add an element when we are in the loop
    }
    else
    { // wants to bind
        if (!setReuseAddr())
        {
            sysClose();
            return; // XXX what can we do?
        }

        sys_result = bind(fd, (const struct sockaddr *)&sa, sizeof(sa));
        if (sys_result == SOCKET_ERROR)
        {
            error=GET_NET_ERROR();
            sysClose();
            onBindError();
            return; // XXX what can we do?
        }

        if (stype == LISTEN_TCP)
        {
            sys_result = listen(fd, 10);
            if (sys_result == SOCKET_ERROR)
            {
                error=GET_NET_ERROR();
                sysClose();
                onListenError();
                return; // XXX what can we do?
            }
            NSocketManager::add_to_list(this); // XXX should put some onListening()?
        }
    }

    if ( (stype == TCP || stype == UDP) && !is_connecting ) // if we are here is because we are connected
        onSocketReady();


//  #error "Not ready for this compiler"
#endif

}