xref: /haiku/src/kits/network/libnetapi/DatagramSocket.cpp (revision a31d07a2a9d1aee9b9bb04f6bf2a5829f5d92960)
1 /*
2  * Copyright 2011, Axel Dörfler, axeld@pinc-software.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include <DatagramSocket.h>
8 
9 #include <errno.h>
10 
11 
12 //#define TRACE_SOCKET
13 #ifdef TRACE_SOCKET
14 #	define TRACE(x...) printf(x)
15 #else
16 #	define TRACE(x...) ;
17 #endif
18 
19 
BDatagramSocket()20 BDatagramSocket::BDatagramSocket()
21 {
22 }
23 
24 
BDatagramSocket(const BNetworkAddress & peer,bigtime_t timeout)25 BDatagramSocket::BDatagramSocket(const BNetworkAddress& peer, bigtime_t timeout)
26 {
27 	Connect(peer, timeout);
28 }
29 
30 
BDatagramSocket(const BDatagramSocket & other)31 BDatagramSocket::BDatagramSocket(const BDatagramSocket& other)
32 	:
33 	BAbstractSocket(other)
34 {
35 }
36 
37 
~BDatagramSocket()38 BDatagramSocket::~BDatagramSocket()
39 {
40 }
41 
42 
43 status_t
Bind(const BNetworkAddress & local,bool reuseAddr)44 BDatagramSocket::Bind(const BNetworkAddress& local, bool reuseAddr)
45 {
46 	return BAbstractSocket::Bind(local, reuseAddr, SOCK_DGRAM);
47 }
48 
49 
50 status_t
Accept(BAbstractSocket * & _socket)51 BDatagramSocket::Accept(BAbstractSocket*& _socket)
52 {
53 	return B_NOT_SUPPORTED;
54 }
55 
56 
57 status_t
Connect(const BNetworkAddress & peer,bigtime_t timeout)58 BDatagramSocket::Connect(const BNetworkAddress& peer, bigtime_t timeout)
59 {
60 	return BAbstractSocket::Connect(peer, SOCK_DGRAM, timeout);
61 }
62 
63 
64 status_t
SetBroadcast(bool broadcast)65 BDatagramSocket::SetBroadcast(bool broadcast)
66 {
67 	int value = broadcast ? 1 : 0;
68 	if (setsockopt(fSocket, SOL_SOCKET, SO_BROADCAST, &value, sizeof(value))
69 			!= 0)
70 		return errno;
71 
72 	return B_OK;
73 }
74 
75 
76 void
SetPeer(const BNetworkAddress & peer)77 BDatagramSocket::SetPeer(const BNetworkAddress& peer)
78 {
79 	fPeer = peer;
80 }
81 
82 
83 size_t
MaxTransmissionSize() const84 BDatagramSocket::MaxTransmissionSize() const
85 {
86 	// TODO: might vary on family!
87 	return 32768;
88 }
89 
90 
91 ssize_t
SendTo(const BNetworkAddress & address,const void * buffer,size_t size)92 BDatagramSocket::SendTo(const BNetworkAddress& address, const void* buffer,
93 	size_t size)
94 {
95 	ssize_t bytesSent = sendto(fSocket, buffer, size, 0, address,
96 		address.Length());
97 	if (bytesSent < 0)
98 		return errno;
99 
100 	return bytesSent;
101 }
102 
103 
104 ssize_t
ReceiveFrom(void * buffer,size_t bufferSize,BNetworkAddress & from)105 BDatagramSocket::ReceiveFrom(void* buffer, size_t bufferSize,
106 	BNetworkAddress& from)
107 {
108 	socklen_t fromLength = sizeof(sockaddr_storage);
109 	ssize_t bytesReceived = recvfrom(fSocket, buffer, bufferSize, 0,
110 		from, &fromLength);
111 	if (bytesReceived < 0)
112 		return errno;
113 
114 	return bytesReceived;
115 }
116 
117 
118 //	#pragma mark - BDataIO implementation
119 
120 
121 ssize_t
Read(void * buffer,size_t size)122 BDatagramSocket::Read(void* buffer, size_t size)
123 {
124 	ssize_t bytesReceived = recv(Socket(), buffer, size, 0);
125 	if (bytesReceived < 0) {
126 		TRACE("%p: BSocket::Read() error: %s\n", this, strerror(errno));
127 		return errno;
128 	}
129 
130 	return bytesReceived;
131 }
132 
133 
134 ssize_t
Write(const void * buffer,size_t size)135 BDatagramSocket::Write(const void* buffer, size_t size)
136 {
137 	ssize_t bytesSent;
138 
139 	if (!fIsConnected)
140 		bytesSent = sendto(Socket(), buffer, size, 0, fPeer, fPeer.Length());
141 	else
142 		bytesSent = send(Socket(), buffer, size, 0);
143 
144 	if (bytesSent < 0) {
145 		TRACE("%p: BDatagramSocket::Write() error: %s\n", this,
146 			strerror(errno));
147 		return errno;
148 	}
149 
150 	return bytesSent;
151 }
152