bool Thread::start() {
     int thread_create_status = pthread_create(&(this->thread), NULL,
         Thread::_thread_start, this);
     EPYX_ASSERT(thread_create_status == 0);
     EPYX_ASSERT(this->thread != 0);
     return true;
 }
Exemple #2
0
    int UDPSocket::recv(void * data, int size) {
        int bytes;
        struct sockaddr_storage saddr;
        socklen_t length = sizeof (saddr);
        EPYX_ASSERT(data != NULL);
        EPYX_ASSERT(this->sock >= 0);
        bytes = ::recvfrom(this->sock, data, size, 0, (struct sockaddr *) &saddr, &length);
        // TODO: Implement status error (eg. Conn closed, ...)
        if (bytes < 0)
            throw ErrException("UDPSocket", "recvfrom");

        if (bytes == 0) {
            //Socket is now closed
            EPYX_VERIFY(sock < 0);
            return 0;
        }

        /**
         * recv doesn't set the after-the-last byte to zero. We must do it to
         * avoid some issues.
         * (writing into a prefilled longer data buffer f***s everything up)
         */
        if (bytes < size)
            ((char*) data)[bytes] = 0;
        lastRecvAddr = SockAddress((const sockaddr *) &saddr);
        return bytes;
    }
Exemple #3
0
    /**
     * Send bytes through the network
     * return: number of sent bytes
     */
    int TCPSocket::send(const void *data, int size)
    {
        int bytes;
        EPYX_ASSERT(data != NULL);
        if (!this->isConnected)
            this->connect();
        EPYX_ASSERT(this->sock >= 0);
        EPYX_ASSERT(this->isConnected);
        bytes = ::send(this->sock, data, size, 0);
        // TODO: Implement status error (ex. Conn closed, ...)

        if (bytes == -1)
            throw ErrException("Socket", "send");
        return bytes;
    }
 bool Socket::sendAll(const void *data, int size) {
     int sentBytes;
     EPYX_ASSERT(data != NULL);
     while (size > 0) {
         sentBytes = this->send(data, size);
         if (!sentBytes) {
             log::error << "Socket::sendAll was unable to send " << size <<
                 " bytes" << log::endl;
             return false;
         }
         EPYX_ASSERT(sentBytes <= size);
         size -= sentBytes;
     }
     return true;
 }
Exemple #5
0
    N2npNodeId LocalRelay::attachNode(LocalNode *node)
    {
        std::string nodeName;

        // Make this thread-safe
        this->nodesMutex.lock();
        try {
            // Compute a new Unique ID
            std::ostringstream nodeNameStream;
            nodeNameStream << (++this->lastNodeId);
            nodeName = nodeNameStream.str();
        } catch (Exception e) {
            this->nodesMutex.unlock();
            throw e;
        }
        this->nodesMutex.unlock();

        N2npNodeId nodeId(nodeName.c_str(), this->addr);

        // This may not happen, as this is an auto-increment index
        EPYX_ASSERT(this->nodes.count(nodeName) == 0);

        this->nodesMutex.lock();
        this->nodes.insert(make_pair(nodeName, node));
        this->nodesMutex.unlock();

        return nodeId;
    }
    struct timeval Timeout::remainingTimeval() const {
        struct timeval tv;
        int gettimeofday_status = gettimeofday(&tv, NULL);
        EPYX_ASSERT(gettimeofday_status == 0);

        if (tv.tv_sec > maxTime.tv_sec) {
            // Timeout in seconds
            tv.tv_sec = 0;
            tv.tv_usec = 0;
            return tv;
        }
        tv.tv_sec = maxTime.tv_sec - tv.tv_sec;
        if (tv.tv_usec > maxTime.tv_usec) {
            if (tv.tv_sec == 0) {
                // Timeout in microseconds
                tv.tv_usec = 0;
                return tv;
            }
            // Time difference with a reminder
            tv.tv_sec--;
            tv.tv_usec = 1000000 + maxTime.tv_usec - tv.tv_usec;
        } else {
            tv.tv_usec = maxTime.tv_usec - tv.tv_usec;
        }
        return tv;
    }
    IpAddress::IpAddress(const struct sockaddr *saddr) {
        EPYX_ASSERT(saddr != NULL);
        char ipBuffer[INET6_ADDRSTRLEN + 1];

        if (saddr->sa_family == AF_INET) {
            // IPv4
            struct sockaddr_in *ipv4 = (struct sockaddr_in *) saddr;
            inet_ntop(AF_INET, &(ipv4->sin_addr), ipBuffer, sizeof (ipBuffer));
            this->ip.assign(ipBuffer);
            this->ipVersion = 4;
        } else if (saddr->sa_family == AF_INET6) {
            // IPv6
            struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *) saddr;
            inet_ntop(AF_INET6, &(ipv6->sin6_addr), ipBuffer, sizeof (ipBuffer));
            this->ip.assign(ipBuffer);
            this->ipVersion = 6;
        } else {
            log::fatal << "You have just invented a new IP version " \
                << "without giving me information about how to handle it\n" \
                << "The version is: " << saddr->sa_family << "\n" \
                << "IPv4 is: " << AF_INET << "\n" \
                << "IPv6 is: " << AF_INET6 \
                << log::endl;
            throw FailException("IpAddress", "Bad IP Version");
        }
    }
 bool Socket::recvBytes(byte_str *data, int size) {
     EPYX_ASSERT(data != NULL);
     std::unique_ptr<byte[]> bytes(new byte[size]);
     if (!this->recvAll(bytes.get(), size)) return false;
     data->assign(bytes.get());
     return true;
 }
 bool Socket::recvAll(void *data, int size) {
     int recvBytes;
     EPYX_ASSERT(data != NULL);
     // TODO: stop on feof !
     while (size > 0) {
         recvBytes = this->recv(data, size);
         if (!recvBytes) {
             log::error << "Socket::recvAll was unable to receive " << size <<
                 " bytes" << log::endl;
             return false;
         }
         EPYX_ASSERT(recvBytes <= size);
         size -= recvBytes;
     }
     return true;
 }
Exemple #10
0
    bool Server::_internal_bind(int socktype)
    {
        //EPYX_ASSERT(port < 65536);
        char charport[10];
        struct addrinfo hints, *addrAll, *pai;
        int status, flag;

        // Convert port to char* to find address hints
        snprintf(charport, sizeof(charport), "%u", port);
        memset(&hints, 0, sizeof hints);
        // AF_INET or AF_INET6 to force IP version
        hints.ai_family = AF_UNSPEC;
        // SOCK_STREAM (TCP) or SOCK_DGRAM (UDP)
        hints.ai_socktype = socktype;
        // Server = passive
        hints.ai_flags = AI_PASSIVE;
        status = ::getaddrinfo(NULL, charport, &hints, &addrAll);
        if (status != 0) {
            log::fatal << "getaddrinfo error " << status << ": "
                << gai_strerror(status) << log::endl;
            throw FailException("TCPServer::bind", "getaddrinfo error");
        }

        // getaddrinfo() returns a list of address structures.
        // Try each address until we successfully bind.
        for (pai = addrAll; pai != NULL; pai = pai->ai_next) {
            // Create a new socket
            this->sockfd = ::socket(pai->ai_family, pai->ai_socktype,
                pai->ai_protocol);
            if (this->sockfd == -1)
                continue;

            // Allow reusing the address (ignore failure)
            flag = 1;
            setsockopt(this->sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(int));

            // Bind to a listening address/port
            status = ::bind(this->sockfd, pai->ai_addr, pai->ai_addrlen);
            if (status == 0) {
                // Success : remember used address
                this->address = Address(pai->ai_addr);
                break;
            }
            log::warn << "bind(" << Address(pai->ai_addr) << "): " << log::errstd << log::endl;

            // Close socket if bind fails
            ::close(this->sockfd);
            this->sockfd = -1;
        }
        // Free results
        freeaddrinfo(addrAll);
        if (pai == NULL) {
            log::debug << "Nowhere to bind." << log::endl;
            return false;
        }

        // Now there is a socket, listen to nbConn connections
        EPYX_ASSERT(sockfd >= 0);
        return true;
    }
 void Thread::term() {
     if (this->thread != 0) {
         int thread_cancel_status = pthread_cancel(this->thread);
         // Thread may have disappeared
         EPYX_ASSERT(thread_cancel_status == 0 || thread_cancel_status == ESRCH);
         this->thread = 0;
     }
 }
    bool Timeout::hasExpired() const {
        struct timeval tv;
        int gettimeofday_status = gettimeofday(&tv, NULL);
        EPYX_ASSERT(gettimeofday_status == 0);

        return (tv.tv_sec > maxTime.tv_sec) ||
            (tv.tv_sec == maxTime.tv_sec && tv.tv_usec > maxTime.tv_usec);
    }
    Timeout::Timeout(unsigned int ms) {
        struct timeval tv;
        int gettimeofday_status = gettimeofday(&tv, NULL);
        EPYX_ASSERT(gettimeofday_status == 0);

        long usec = tv.tv_usec + (1000 * ms);
        maxTime.tv_usec = usec % 1000000;
        maxTime.tv_sec = tv.tv_sec + (usec / 1000000);
    }
Exemple #14
0
    /**
     * Receive some bytes from the network in a buffer
     * @data: buffer pointer
     * @size: buffer size
     * return: number of bytes received
     */
    int TCPSocket::recv(void *data, int size)
    {
        int bytes;
        EPYX_ASSERT(data != NULL);
        EPYX_ASSERT(this->sock >= 0);
        EPYX_ASSERT(this->isConnected);
        bytes = ::recv(this->sock, data, size, 0);
        // TODO: Implement status error (eg. Conn closed, ...)
        if (bytes == -1)
            throw ErrException("Socket", "recv");

        /**
         * recv doesn't set the after-the-last byte to zero. We must do it to
         * avoid some issues.
         * (writing into a prefilled longer data buffer f***s everything up)
         */
        if (bytes < size)
            ((char*) data)[bytes] = 0;
        return bytes;
    }
Exemple #15
0
int main(){
    std::string msgName;
    char message[MAXLENGTH];
    Epyx::Thread::init();
    Epyx::log::init(Epyx::log::CONSOLE, "");
    try {
        Epyx::GTTParser myParser;
        // TODO: Use argc/argv to get msg.txt path
        std::ifstream msgList("msg.txt");
        if(!msgList) {
            Epyx::log::fatal << "Please provide `msg.txt' to indicate all filenames of messages"
                    << Epyx::log::endl;
            throw Epyx::FailException("testParser", "No message list found");
        }

        while (!msgList.eof()) {
            getline(msgList, msgName);
            // Remove space characters
            Epyx::String::trim(msgName);
            if (msgName.empty())
                continue;
            Epyx::log::debug << "Read message `" << msgName << "'" << Epyx::log::endl;
            std::ifstream msgInput(msgName.c_str(), std::ios_base::in|std::ios_base::binary);
            if(!msgInput){
                Epyx::log::fatal << "Unable to read `" << msgName << "'" << Epyx::log::endl;
                throw Epyx::FailException("testParser", "Message error");
            }

            while (!msgInput.eof()) {
                msgInput.read(message, sizeof message);
                int size = msgInput.gcount();
                if (size > 0)
                    myParser.eat(message, size);
                else {
                    // A reading probleme MUST be because end of file happens
                    EPYX_ASSERT(msgInput.eof());
                }
                Epyx::GTTPacket *pac;
                while((pac = myParser.getPacket()) != NULL){
                    Epyx::log::info << "here comes one packet:\n"
                        << *pac << Epyx::log::endl;
                }
            }
            msgInput.close();
        }
        msgList.close();
    } catch (Epyx::Exception e) {
        Epyx::log::fatal << e << Epyx::log::endl;
    }
    Epyx::log::flushAndQuit();
    return 0;
}
 void IpAddress::getSockAddr(struct sockaddr *saddr, unsigned short port) const {
     EPYX_ASSERT(saddr != NULL);
     EPYX_ASSERT(this->ipVersion > 0);
     if (this->ipVersion == 4) {
         // IPv4
         struct sockaddr_in *ipv4 = (struct sockaddr_in *) saddr;
         memset(&(ipv4->sin_zero), 0, sizeof (ipv4->sin_zero));
         ipv4->sin_family = AF_INET;
         inet_pton(AF_INET, ip.c_str(), &(ipv4->sin_addr));
         ipv4->sin_port = htons(port);
     } else if (this->ipVersion == 6) {
         // IPv6
         struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *) saddr;
         ipv6->sin6_family = AF_INET6;
         ipv6->sin6_flowinfo = 0;
         ipv6->sin6_scope_id = 0;
         inet_pton(AF_INET6, ip.c_str(), &(ipv6->sin6_addr));
         ipv6->sin6_port = htons(port);
     } else {
         throw FailException("IpAddress", "Bad IP Version");
     }
 }
 void Socket::updateLocalAddress() {
     EPYX_ASSERT(sock >= 0);
     struct sockaddr_storage saddr;
     socklen_t saddr_len = sizeof (saddr);
     if (::getsockname(sock, (struct sockaddr *) &saddr, &saddr_len) < 0) {
         log::warn << "Socket::updateLocalAddress: getsockname error "
             << log::errstd << log::endl;
         // Do nothing
         return;
     }
     // Update address
     localAddress = SockAddress((struct sockaddr *) &saddr);
 }
 void* Thread::_thread_start(void *arg) {
     try {
         // Call Thread::run()
         Epyx::Thread *self = (Epyx::Thread*) arg;
         EPYX_ASSERT(self != NULL);
         Thread::setName(self->name);
         self->run();
     } catch (std::exception& e) {
         log::fatal << "Thread exception !" << log::endl;
         log::fatal << e.what() << log::endl;
     }
     return NULL;
 }
    TCPServer::TCPServer(const SockAddress& addr, unsigned int nbConn)
    :Server(addr) {
        if (!this->_internal_bind(SOCK_STREAM))
            return;

        // Now there is a socket, listen to nbConn connections
        EPYX_ASSERT(sockfd >= 0);
        int status = listen(sockfd, nbConn);
        if (status < 0) {
            log::error << "listen: " << log::errstd << log::endl;
            this->close();
            return;
        }
    }
Exemple #20
0
 void* Thread::_thread_start(void *arg)
 {
     try {
         // Call Thread::run()
         Epyx::Thread *self = (Epyx::Thread*) arg;
         EPYX_ASSERT(self != NULL);
         detail::thread_infos->reset(self->info);
         self->run();
     } catch (Exception e) {
         log::fatal << "Thread exception !" << log::endl;
         log::fatal << e << log::endl;
     }
     return NULL;
 }
Exemple #21
0
 void Thread::setName(const std::string name, int id)
 {
     //Set up oly once the thread info for this thread
     EPYX_ASSERT(info == NULL);
     info = new detail::ThreadInfo();
     // Copy name
     if (id != -1) {
         std::ostringstream str;
         str << name << " " << id;
         info->name = str.str();
     } else {
         info->name = name;
     }
 }
Exemple #22
0
    int UDPSocket::send(const void *data, int size) {
        int bytes;
        struct sockaddr_storage saddr;

        EPYX_ASSERT(data != NULL);
        // Create a new socket if it does not exist
        if (sock < 0) {
            this->create();
        }
        address.getSockAddr((struct sockaddr *) &saddr);
        bytes = ::sendto(sock, data, size, 0, (const struct sockaddr *) &saddr, sizeof (saddr));
        if (localAddress.empty())
            this->updateLocalAddress();
        // TODO: Implement status error (ex. Conn closed, ...)

        if (bytes < 0)
            throw ErrException("UDPSocket", "sendto");
        return bytes;
    }
Exemple #23
0
 void run()
 {
     EPYX_ASSERT(sock != NULL && srv != NULL);
     try {
         // Call real function
         srv->runSocket(*sock);
         log::debug << "Client terminated (was " << sock->getAddress()
                    << ")" << log::endl;
         delete sock;
         sock = NULL;
     } catch (Exception e) {
         log::error << "Error from " << sock->getAddress()
                    << " : " << e << log::endl;
     }
     // Close socket
     delete sock;
     // Yes, we can do it !
     // FIXME: change this !
     delete this;
 }
Exemple #24
0
    void GTTParser::eat(const char *data, long size)
    {
        EPYX_ASSERT(data != NULL && size > 0);

        // Append data to reminded
        if (reminded != NULL) {
            char *tmp = new char[remindedSize + size + 1];
            memcpy(tmp, reminded, remindedSize);
            memcpy(tmp + remindedSize, data, size);
            delete[] reminded;
            reminded = tmp;
            remindedSize += size;
        } else {
            reminded = new char[size + 1];
            remindedSize = size;
            memcpy(reminded, data, size);
        }
        // Add a zero at the end to be sure string terminates
        reminded[remindedSize] = 0;
    }
    bool NetSelectSocket::read() {
        EPYX_ASSERT(sock);
        const int size = 4096;
        byte data[size];
        int recvSize = sock->recv(data, size);

        // Quit on End-Of-File
        if (recvSize == 0)
            return false;

        // Eat data
        try {
            this->eat(byte_str(data, recvSize));
        } catch (MinorException e) {
            log::error << e << log::endl;
            log::error << "Closing socket to " << sock->getAddress() <<
                " due to an exception" << log::endl;
            return false;
        }
        return sock->isOpened();
    }
Exemple #26
0
 void Thread::term()
 {
     int thread_cancel_status = pthread_cancel(this->thread);
     EPYX_ASSERT(thread_cancel_status == 0);
     this->thread = 0;
 }
Exemple #27
0
 void Thread::wait()
 {
     EPYX_ASSERT(this->thread != 0);
     int thread_join_status = pthread_join(this->thread, NULL);
     EPYX_ASSERT(thread_join_status == 0);
 }
Exemple #28
0
 const std::string& Thread::getThisName()
 {
     EPYX_ASSERT(info != NULL);
     return info->name;
 }
 const std::shared_ptr<Socket>& NetSelectSocket::socket() const {
     EPYX_ASSERT(sock);
     return sock;
 }
 int NetSelectSocket::getFileDescriptor() const {
     EPYX_ASSERT(sock);
     return sock->getFd();
 }