xref: /haiku/src/kits/network/libnetapi/Socket.cpp (revision 611d3d780334f697e8cd7836dcaa5fde21776da6)
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