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
210e478f5aSAxel DörflerBSocket::BSocket()
220e478f5aSAxel Dörfler{
230e478f5aSAxel Dörfler}
240e478f5aSAxel Dörfler
250e478f5aSAxel Dörfler
260e478f5aSAxel DörflerBSocket::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
320e478f5aSAxel DörflerBSocket::BSocket(const BSocket& other)
330e478f5aSAxel Dörfler	:
340e478f5aSAxel Dörfler	BAbstractSocket(other)
350e478f5aSAxel Dörfler{
360e478f5aSAxel Dörfler}
370e478f5aSAxel Dörfler
380e478f5aSAxel Dörfler
390e478f5aSAxel DörflerBSocket::~BSocket()
400e478f5aSAxel Dörfler{
410e478f5aSAxel Dörfler}
420e478f5aSAxel Dörfler
430e478f5aSAxel Dörfler
440e478f5aSAxel Dörflerstatus_t
45c9dd7d0dSRene GollentBSocket::Bind(const BNetworkAddress& local, bool reuseAddr)
460e478f5aSAxel Dörfler{
47c9dd7d0dSRene Gollent	return BAbstractSocket::Bind(local, SOCK_STREAM, reuseAddr);
480e478f5aSAxel Dörfler}
490e478f5aSAxel Dörfler
500e478f5aSAxel Dörfler
510e478f5aSAxel Dörflerstatus_t
520e478f5aSAxel DörflerBSocket::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 Gollentstatus_t
59c9dd7d0dSRene GollentBSocket::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örflerssize_t
820e478f5aSAxel DörflerBSocket::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örflerssize_t
950e478f5aSAxel DörflerBSocket::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örflervoid
1110e478f5aSAxel DörflerBSocket::_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