blob: 66a03f359a20d9fa8c3041749929bda4d562f94c [file] [log] [blame]
Tristan Matthews0a329cc2013-07-17 13:20:14 -04001/* $Id$ */
2/*
3 * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#ifndef __PJPP_SOCK_HPP__
21#define __PJPP_SOCK_HPP__
22
23#include <pj/sock.h>
24#include <pj/string.h>
25
26class Pj_Event_Handler;
27
28//
29// Base class for address.
30//
31class Pj_Addr
32{
33};
34
35//
36// Internet address.
37//
38class Pj_Inet_Addr : public pj_sockaddr_in, public Pj_Addr
39{
40public:
41 //
42 // Get port number.
43 //
44 pj_uint16_t get_port_number() const
45 {
46 return pj_sockaddr_in_get_port(this);
47 }
48
49 //
50 // Set port number.
51 //
52 void set_port_number(pj_uint16_t port)
53 {
54 sin_family = PJ_AF_INET;
55 pj_sockaddr_in_set_port(this, port);
56 }
57
58 //
59 // Get IP address.
60 //
61 pj_uint32_t get_ip_address() const
62 {
63 return pj_sockaddr_in_get_addr(this).s_addr;
64 }
65
66 //
67 // Get address string.
68 //
69 const char *get_address() const
70 {
71 return pj_inet_ntoa(sin_addr);
72 }
73
74 //
75 // Set IP address.
76 //
77 void set_ip_address(pj_uint32_t addr)
78 {
79 sin_family = PJ_AF_INET;
80 pj_sockaddr_in_set_addr(this, addr);
81 }
82
83 //
84 // Set address.
85 //
86 pj_status_t set_address(const pj_str_t *addr)
87 {
88 return pj_sockaddr_in_set_str_addr(this, addr);
89 }
90
91 //
92 // Set address.
93 //
94 pj_status_t set_address(const char *addr)
95 {
96 pj_str_t s;
97 return pj_sockaddr_in_set_str_addr(this, pj_cstr(&s, addr));
98 }
99
100 //
101 // Compare for equality.
102 //
103 bool operator==(const Pj_Inet_Addr &rhs) const
104 {
105 return sin_family == rhs.sin_family &&
106 sin_addr.s_addr == rhs.sin_addr.s_addr &&
107 sin_port == rhs.sin_port;
108 }
109
110private:
111 //
112 // Dummy length used in pj_ioqueue_recvfrom() etc
113 //
114 friend class Pj_Event_Handler;
115 friend class Pj_Socket;
116 friend class Pj_Sock_Stream;
117 friend class Pj_Sock_Dgram;
118
119 int addrlen_;
120};
121
122
123//
124// Socket base class.
125//
126// Note:
127// socket will not automatically be closed on destructor.
128//
129class Pj_Socket
130{
131public:
132 //
133 // Default constructor.
134 //
135 Pj_Socket()
136 : sock_(PJ_INVALID_SOCKET)
137 {
138 }
139
140 //
141 // Initialize from a socket handle.
142 //
143 explicit Pj_Socket(pj_sock_t sock)
144 : sock_(sock)
145 {
146 }
147
148 //
149 // Copy constructor.
150 //
151 Pj_Socket(const Pj_Socket &rhs)
152 : sock_(rhs.sock_)
153 {
154 }
155
156 //
157 // Destructor will not close the socket.
158 // You must call close() explicitly.
159 //
160 ~Pj_Socket()
161 {
162 }
163
164 //
165 // Set socket handle.
166 //
167 void set_handle(pj_sock_t sock)
168 {
169 sock_ = sock;
170 }
171
172 //
173 // Get socket handle.
174 //
175 pj_sock_t get_handle() const
176 {
177 return sock_;
178 }
179
180 //
181 // Get socket handle.
182 //
183 pj_sock_t& get_handle()
184 {
185 return sock_;
186 }
187
188 //
189 // See if the socket is valid.
190 //
191 bool is_valid() const
192 {
193 return sock_ != PJ_INVALID_SOCKET;
194 }
195
196 //
197 // Create the socket.
198 //
199 pj_status_t create(int af, int type, int proto)
200 {
201 return pj_sock_socket(af, type, proto, &sock_);
202 }
203
204 //
205 // Bind socket.
206 //
207 pj_status_t bind(const Pj_Inet_Addr &addr)
208 {
209 return pj_sock_bind(sock_, &addr, sizeof(Pj_Inet_Addr));
210 }
211
212 //
213 // Close socket.
214 //
215 pj_status_t close()
216 {
217 pj_sock_close(sock_);
218 }
219
220 //
221 // Get peer socket name.
222 //
223 pj_status_t getpeername(Pj_Inet_Addr *addr)
224 {
225 return pj_sock_getpeername(sock_, addr, &addr->addrlen_);
226 }
227
228 //
229 // getsockname
230 //
231 pj_status_t getsockname(Pj_Inet_Addr *addr)
232 {
233 return pj_sock_getsockname(sock_, addr, &addr->addrlen_);
234 }
235
236 //
237 // getsockopt.
238 //
239 pj_status_t getsockopt(pj_uint16_t level, pj_uint16_t optname,
240 void *optval, int *optlen)
241 {
242 return pj_sock_getsockopt(sock_, level, optname, optval, optlen);
243 }
244
245 //
246 // setsockopt
247 //
248 pj_status_t setsockopt(pj_uint16_t level, pj_uint16_t optname,
249 const void *optval, int optlen)
250 {
251 return pj_sock_setsockopt(sock_, level, optname, optval, optlen);
252 }
253
254 //
255 // receive data.
256 //
257 pj_ssize_t recv(void *buf, pj_size_t len, int flag = 0)
258 {
259 pj_ssize_t bytes = len;
260 if (pj_sock_recv(sock_, buf, &bytes, flag) != PJ_SUCCESS)
261 return -1;
262 return bytes;
263 }
264
265 //
266 // send data.
267 //
268 pj_ssize_t send(const void *buf, pj_ssize_t len, int flag = 0)
269 {
270 pj_ssize_t bytes = len;
271 if (pj_sock_send(sock_, buf, &bytes, flag) != PJ_SUCCESS)
272 return -1;
273 return bytes;
274 }
275
276 //
277 // connect.
278 //
279 pj_status_t connect(const Pj_Inet_Addr &addr)
280 {
281 return pj_sock_connect(sock_, &addr, sizeof(Pj_Inet_Addr));
282 }
283
284 //
285 // assignment.
286 //
287 Pj_Socket &operator=(const Pj_Socket &rhs)
288 {
289 sock_ = rhs.sock_;
290 return *this;
291 }
292
293protected:
294 friend class Pj_Event_Handler;
295 pj_sock_t sock_;
296};
297
298
299#if PJ_HAS_TCP
300//
301// Stream socket.
302//
303class Pj_Sock_Stream : public Pj_Socket
304{
305public:
306 //
307 // Default constructor.
308 //
309 Pj_Sock_Stream()
310 {
311 }
312
313 //
314 // Initialize from a socket handle.
315 //
316 explicit Pj_Sock_Stream(pj_sock_t sock)
317 : Pj_Socket(sock)
318 {
319 }
320
321 //
322 // Copy constructor.
323 //
324 Pj_Sock_Stream(const Pj_Sock_Stream &rhs) : Pj_Socket(rhs)
325 {
326 }
327
328 //
329 // Assignment.
330 //
331 Pj_Sock_Stream &operator=(const Pj_Sock_Stream &rhs)
332 {
333 sock_ = rhs.sock_;
334 return *this;
335 }
336
337 //
338 // listen()
339 //
340 pj_status_t listen(int backlog = 5)
341 {
342 return pj_sock_listen(sock_, backlog);
343 }
344
345 //
346 // blocking accept()
347 //
348 Pj_Sock_Stream accept(Pj_Inet_Addr *remote_addr = NULL)
349 {
350 pj_sock_t newsock;
351 int *addrlen = remote_addr ? &remote_addr->addrlen_ : NULL;
352 pj_status_t status;
353
354 status = pj_sock_accept(sock_, &newsock, remote_addr, addrlen);
355 if (status != PJ_SUCCESS)
356 return Pj_Sock_Stream(-1);
357
358 return Pj_Sock_Stream(newsock);
359 }
360
361 //
362 // shutdown()
363 //
364 pj_status_t shutdown(int how = PJ_SHUT_RDWR)
365 {
366 return pj_sock_shutdown(sock_, how);
367 }
368
369};
370#endif
371
372//
373// Datagram socket.
374//
375class Pj_Sock_Dgram : public Pj_Socket
376{
377public:
378 //
379 // Default constructor.
380 //
381 Pj_Sock_Dgram()
382 {
383 }
384
385 //
386 // Initialize from a socket handle.
387 //
388 explicit Pj_Sock_Dgram(pj_sock_t sock)
389 : Pj_Socket(sock)
390 {
391 }
392
393 //
394 // Copy constructor.
395 //
396 Pj_Sock_Dgram(const Pj_Sock_Dgram &rhs)
397 : Pj_Socket(rhs)
398 {
399 }
400
401 //
402 // Assignment.
403 //
404 Pj_Sock_Dgram &operator=(const Pj_Sock_Dgram &rhs)
405 {
406 Pj_Socket::operator =(rhs);
407 return *this;
408 }
409
410 //
411 // recvfrom()
412 //
413 pj_ssize_t recvfrom( void *buf, pj_size_t len, int flag = 0,
414 Pj_Inet_Addr *fromaddr = NULL)
415 {
416 pj_ssize_t bytes = len;
417 int *addrlen = fromaddr ? &fromaddr->addrlen_ : NULL;
418 if (pj_sock_recvfrom( sock_, buf, &bytes, flag,
419 fromaddr, addrlen) != PJ_SUCCESS)
420 {
421 return -1;
422 }
423 return bytes;
424 }
425
426 //
427 // sendto()
428 //
429 pj_ssize_t sendto( const void *buf, pj_size_t len, int flag,
430 const Pj_Inet_Addr &addr)
431 {
432 pj_ssize_t bytes = len;
433 if (pj_sock_sendto( sock_, buf, &bytes, flag,
434 &addr, sizeof(pj_sockaddr_in)) != PJ_SUCCESS)
435 {
436 return -1;
437 }
438 return bytes;
439 }
440};
441
442
443#endif /* __PJPP_SOCK_HPP__ */
444