From 9248c1d7976ba1c37e3df147a1eb3115fe72c8d0 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sun, 11 Sep 2016 22:15:35 +0200 Subject: Drop SLIP, Refactor sockets, improve TCP output Quite a large refactoring of the sockets, TCP and UDP, in order to improve the ETI-over-TCP output. This can now accept several simultaneous connections, and requires a throttle. The SLIP input is gone. The UDP inputs are currently broken. --- src/TcpSocket.cpp | 385 ++++++++++++++---------------------------------------- 1 file changed, 98 insertions(+), 287 deletions(-) (limited to 'src/TcpSocket.cpp') diff --git a/src/TcpSocket.cpp b/src/TcpSocket.cpp index 75b320f..13efece 100644 --- a/src/TcpSocket.cpp +++ b/src/TcpSocket.cpp @@ -1,6 +1,11 @@ /* Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) + + Copyright (C) 2016 + Matthias P. Braendli, matthias.braendli@mpb.li + + http://www.opendigitalradio.org */ /* This file is part of ODR-DabMux. @@ -20,86 +25,72 @@ */ #include "TcpSocket.h" +#include "Log.h" #include #include #include #include #include +#include -#ifdef _WIN32 -#else -# include -#endif - -#ifdef TRACE_ON -# ifndef TRACE_CLASS -# define TRACE_CLASS(class, func) cout <<"-" <<(class) <<"\t(" < 0 if ok, -1 (SOCKET_ERROR) if error - */ -int TcpSocket::telnetRead(void* data, int size) -{ - TRACE_CLASS("TcpSocket", "read(void*, size)"); - int ret; - - printf("selectCall\n"); - - printf("readread 1\n"); - char *line=GetLine(listenSocket); - ret=strlen(line); - printf("readread 2\n"); - if (ret <= size) - { - strcpy((char*)data, line); - } - else - { -// size_t n = size; - strcpy((char*)data, line); - ret = size; - } - printf("TELNET READ returned %d\n", ret); - return ret; + return 0; } -/** - * Receive a TCP stream. - * @param data The buffer that will receive data. - * @param size The buffer size. - * @return > 0 if ok, -1 (SOCKET_ERROR) if error - */ -int TcpSocket::read(void* data, int size) +TcpSocket::~TcpSocket() { - TRACE_CLASS("TcpSocket", "read(void*, size)"); - - int ret = recv(listenSocket, (char*)data, size, 0); - if (ret == SOCKET_ERROR) { - setInetError("Can't receive TCP packet"); - return -1; - } - return ret; + close(); } - -#define MAX 512 -char* TcpSocket::GetLine(int fd) +ssize_t TcpSocket::recv(void* data, size_t size) { - static char line[MAX]; - static char netread[MAX] = ""; - int n, len; - char *p; - - len = strlen(netread); - - /* look for \r\n in netread buffer */ - p = strstr(netread, "\r\n"); - if (p == NULL) { - /* fill buff - no \r\n found */ - //n = ::read(fd, (void*)(netread+len), (size_t)(MAX-len)); - n = recv(fd, (netread+len), MAX-len, 0); - if (n == SOCKET_ERROR) { - setInetError("Can't receive TCP packet"); - return NULL; + ssize_t ret = ::recv(m_sock, (char*)data, size, 0); + if (ret == SOCKET_ERROR) { + stringstream ss; + ss << "TCP Socket recv error: " << strerror(errno); + throw std::runtime_error(ss.str()); } - len += n; - netread[len] = '\0'; - if (n>0) - return GetLine(fd); - } - if (p!=NULL) - { - *p = '\0'; - strcpy(line, netread); - /* copy rest of buf down */ - memmove(netread, p+2, strlen(p+2)+1); - } - return line; + return ret; } -/** - * Send an TCP packet. - * @param data The buffer taht will be sent. - * @param size Number of bytes to send. - * return 0 if ok, -1 if error - */ -int TcpSocket::write(const void* data, int size) +ssize_t TcpSocket::send(const void* data, size_t size) { -#ifdef DUMP - TRACE_CLASS("TcpSocket", "write(const void*, int)"); -#endif + /* Without MSG_NOSIGNAL the process would receive a SIGPIPE and die */ + ssize_t ret = ::send(m_sock, (const char*)data, size, MSG_NOSIGNAL); - // ignore BROKENPIPE signal (we handle it instead) -// void* old_sigpipe = signal ( SIGPIPE, SIG_IGN ); - // try to send data - int ret = send(listenSocket, (const char*)data, size, 0 /*MSG_NOSIGNAL*/ ); - // restore the BROKENPIPE handling -// signal ( SIGPIPE, (__sighandler_t)old_sigpipe ); - if (ret == SOCKET_ERROR) { - setInetError("Can't send TCP packet"); - return -1; - } - return ret; + if (ret == SOCKET_ERROR) { + stringstream ss; + ss << "TCP Socket send error: " << strerror(errno); + throw std::runtime_error(ss.str()); + } + return ret; } - -int TcpSocket::setDestination(InetAddress &addr) +void TcpSocket::listen() { - address = addr; - int ret = connect(listenSocket, addr.getAddress(), sizeof(*addr.getAddress())); - // A etre verifier: code de retour differend entre Linux et Windows - return ret; + if (::listen(m_sock, 1) == SOCKET_ERROR) { + stringstream ss; + ss << "TCP Socket listen error: " << strerror(errno); + throw std::runtime_error(ss.str()); + } } - -void TcpSocket::setSocket(SOCKET socket, InetAddress &addr) +TcpSocket TcpSocket::accept() { - if (listenSocket != INVALID_SOCKET) - closesocket(listenSocket); - listenSocket = socket; - address = addr; + InetAddress remote_addr; + socklen_t addrLen = sizeof(sockaddr_in); + + SOCKET socket = ::accept(m_sock, remote_addr.getAddress(), &addrLen); + if (socket == SOCKET_ERROR) { + stringstream ss; + ss << "TCP Socket accept error: " << strerror(errno); + throw std::runtime_error(ss.str()); + } + else { + TcpSocket client(socket, m_own_address, remote_addr); + return client; + } } - -InetAddress TcpSocket::getAddress() +InetAddress TcpSocket::getOwnAddress() const { - return address; + return m_own_address; } - -int TcpSocket::PeekCount() +InetAddress TcpSocket::getRemoteAddress() const { - int count; - char tempBuffer[3]; - int size=3; - - count = recv(listenSocket, tempBuffer, size, MSG_PEEK); - if (count == -1) - { - printf("ERROR WHEN PEEKING SOCKET\n"); - } - return count; + return m_remote_address; } - -/* -WSAEINTR -WSAEBADF -WSAEACCES -WSAEFAULT -WSAEINVAL -WSAEMFILE -WSAEWOULDBLOCK -WSAEINPROGRESS -WSAEALREADY -WSAENOTSOCK -WSAEDESTADDRREQ -WSAEMSGSIZE -WSAEPROTOTYPE -WSAENOPROTOOPT -WSAEPROTONOSUPPORT -WSAESOCKTNOSUPPORT -WSAEOPNOTSUPP -WSAEPFNOSUPPORT -WSAEAFNOSUPPORT -WSAEADDRINUSE -WSAEADDRNOTAVAIL -WSAENETDOWN -WSAENETUNREACH -WSAENETRESET -WSAECONNABORTED -WSAECONNRESET -WSAENOBUFS -WSAEISCONN -WSAENOTCONN -WSAESHUTDOWN -WSAETOOMANYREFS -WSAETIMEDOUT -WSAECONNREFUSED -WSAELOOP -WSAENAMETOOLONG -WSAEHOSTDOWN -WSAEHOSTUNREACH -WSAENOTEMPTY -WSAEPROCLIM -WSAEUSERS -WSAEDQUOT -WSAESTALE -WSAEREMOTE -WSAEDISCON -WSASYSNOTREADY -WSAVERNOTSUPPORTED -WSANOTINITIALISED -*/ -- cgit v1.2.3