10e478f5aSAxel Dörfler /*
20e478f5aSAxel Dörfler * Copyright 2011, Axel Dörfler, axeld@pinc-software.de.
3c9dd7d0dSRene Gollent * Copyright 2016, Rene Gollent, rene@gollent.com.
40e478f5aSAxel Dörfler * Distributed under the terms of the MIT License.
50e478f5aSAxel Dörfler */
60e478f5aSAxel Dörfler
70e478f5aSAxel Dörfler
80e478f5aSAxel Dörfler #include <Socket.h>
90e478f5aSAxel Dörfler
100dc3ab4fSAugustin Cavalier #include <errno.h>
110e478f5aSAxel Dörfler
12a31d07a2SAugustin Cavalier
130e478f5aSAxel Dörfler //#define TRACE_SOCKET
140e478f5aSAxel Dörfler #ifdef TRACE_SOCKET
150e478f5aSAxel Dörfler # define TRACE(x...) printf(x)
160e478f5aSAxel Dörfler #else
170e478f5aSAxel Dörfler # define TRACE(x...) ;
180e478f5aSAxel Dörfler #endif
190e478f5aSAxel Dörfler
200e478f5aSAxel Dörfler
BSocket()210e478f5aSAxel Dörfler BSocket::BSocket()
220e478f5aSAxel Dörfler {
230e478f5aSAxel Dörfler }
240e478f5aSAxel Dörfler
250e478f5aSAxel Dörfler
BSocket(const BNetworkAddress & peer,bigtime_t timeout)260e478f5aSAxel Dörfler BSocket::BSocket(const BNetworkAddress& peer, bigtime_t timeout)
270e478f5aSAxel Dörfler {
280e478f5aSAxel Dörfler Connect(peer, timeout);
290e478f5aSAxel Dörfler }
300e478f5aSAxel Dörfler
310e478f5aSAxel Dörfler
BSocket(const BSocket & other)320e478f5aSAxel Dörfler BSocket::BSocket(const BSocket& other)
330e478f5aSAxel Dörfler :
340e478f5aSAxel Dörfler BAbstractSocket(other)
350e478f5aSAxel Dörfler {
360e478f5aSAxel Dörfler }
370e478f5aSAxel Dörfler
380e478f5aSAxel Dörfler
~BSocket()390e478f5aSAxel Dörfler BSocket::~BSocket()
400e478f5aSAxel Dörfler {
410e478f5aSAxel Dörfler }
420e478f5aSAxel Dörfler
430e478f5aSAxel Dörfler
440e478f5aSAxel Dörfler status_t
Bind(const BNetworkAddress & local,bool reuseAddr)45c9dd7d0dSRene Gollent BSocket::Bind(const BNetworkAddress& local, bool reuseAddr)
460e478f5aSAxel Dörfler {
47*611d3d78SAugustin Cavalier return BAbstractSocket::Bind(local, reuseAddr, SOCK_STREAM);
480e478f5aSAxel Dörfler }
490e478f5aSAxel Dörfler
500e478f5aSAxel Dörfler
510e478f5aSAxel Dörfler status_t
Connect(const BNetworkAddress & peer,bigtime_t timeout)520e478f5aSAxel Dörfler BSocket::Connect(const BNetworkAddress& peer, bigtime_t timeout)
530e478f5aSAxel Dörfler {
540e478f5aSAxel Dörfler return BAbstractSocket::Connect(peer, SOCK_STREAM, timeout);
550e478f5aSAxel Dörfler }
560e478f5aSAxel Dörfler
570e478f5aSAxel Dörfler
58c9dd7d0dSRene Gollent status_t
Accept(BAbstractSocket * & _socket)59c9dd7d0dSRene Gollent BSocket::Accept(BAbstractSocket*& _socket)
60c9dd7d0dSRene Gollent {
61c9dd7d0dSRene Gollent int fd = -1;
62c9dd7d0dSRene Gollent BNetworkAddress peer;
63c9dd7d0dSRene Gollent status_t error = AcceptNext(fd, peer);
64c9dd7d0dSRene Gollent if (error != B_OK)
65c9dd7d0dSRene Gollent return error;
66c9dd7d0dSRene Gollent BSocket* socket = new(std::nothrow) BSocket();
67c9dd7d0dSRene Gollent if (socket == NULL) {
68c9dd7d0dSRene Gollent close(fd);
69c9dd7d0dSRene Gollent return B_NO_MEMORY;
70c9dd7d0dSRene Gollent }
71c9dd7d0dSRene Gollent
72c9dd7d0dSRene Gollent socket->_SetTo(fd, fLocal, peer);
73c9dd7d0dSRene Gollent _socket = socket;
74c9dd7d0dSRene Gollent return B_OK;
75c9dd7d0dSRene Gollent }
76c9dd7d0dSRene Gollent
77c9dd7d0dSRene Gollent
780e478f5aSAxel Dörfler // #pragma mark - BDataIO implementation
790e478f5aSAxel Dörfler
800e478f5aSAxel Dörfler
810e478f5aSAxel Dörfler ssize_t
Read(void * buffer,size_t size)820e478f5aSAxel Dörfler BSocket::Read(void* buffer, size_t size)
830e478f5aSAxel Dörfler {
840e478f5aSAxel Dörfler ssize_t bytesReceived = recv(Socket(), buffer, size, 0);
850e478f5aSAxel Dörfler if (bytesReceived < 0) {
860e478f5aSAxel Dörfler TRACE("%p: BSocket::Read() error: %s\n", this, strerror(errno));
870e478f5aSAxel Dörfler return errno;
880e478f5aSAxel Dörfler }
890e478f5aSAxel Dörfler
900e478f5aSAxel Dörfler return bytesReceived;
910e478f5aSAxel Dörfler }
920e478f5aSAxel Dörfler
930e478f5aSAxel Dörfler
940e478f5aSAxel Dörfler ssize_t
Write(const void * buffer,size_t size)950e478f5aSAxel Dörfler BSocket::Write(const void* buffer, size_t size)
960e478f5aSAxel Dörfler {
970e478f5aSAxel Dörfler ssize_t bytesSent = send(Socket(), buffer, size, 0);
980e478f5aSAxel Dörfler if (bytesSent < 0) {
990e478f5aSAxel Dörfler TRACE("%p: BSocket::Write() error: %s\n", this, strerror(errno));
1000e478f5aSAxel Dörfler return errno;
1010e478f5aSAxel Dörfler }
1020e478f5aSAxel Dörfler
1030e478f5aSAxel Dörfler return bytesSent;
1040e478f5aSAxel Dörfler }
1050e478f5aSAxel Dörfler
1060e478f5aSAxel Dörfler
1070e478f5aSAxel Dörfler // #pragma mark - private
1080e478f5aSAxel Dörfler
1090e478f5aSAxel Dörfler
1100e478f5aSAxel Dörfler void
_SetTo(int fd,const BNetworkAddress & local,const BNetworkAddress & peer)1110e478f5aSAxel Dörfler BSocket::_SetTo(int fd, const BNetworkAddress& local,
1120e478f5aSAxel Dörfler const BNetworkAddress& peer)
1130e478f5aSAxel Dörfler {
1140e478f5aSAxel Dörfler Disconnect();
1150e478f5aSAxel Dörfler
1160e478f5aSAxel Dörfler fInitStatus = B_OK;
1170e478f5aSAxel Dörfler fSocket = fd;
1180e478f5aSAxel Dörfler fLocal = local;
1190e478f5aSAxel Dörfler fPeer = peer;
120c9dd7d0dSRene Gollent fIsConnected = true;
1210e478f5aSAxel Dörfler
1220e478f5aSAxel Dörfler TRACE("%p: accepted from %s to %s\n", this, local.ToString().c_str(),
1230e478f5aSAxel Dörfler peer.ToString().c_str());
1240e478f5aSAxel Dörfler }
125