blob: 58663dc09e5f95cec475f72d881920f180b41109 [file] [log] [blame]
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001// Copyright (C) 1999-2005 Open Source Telecom Corporation.
2// Copyright (C) 2006-2010 David Sugar, Tycho Softworks.
3//
4// This program is free software; you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation; either version 2 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program; if not, write to the Free Software
16// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17//
18// As a special exception, you may use this file as part of a free software
19// library without restriction. Specifically, if other files instantiate
20// templates or use macros or inline functions from this file, or you compile
21// this file and link it with other files to produce an executable, this
22// file does not by itself cause the resulting executable to be covered by
23// the GNU General Public License. This exception does not however
24// invalidate any other reasons why the executable file might be covered by
25// the GNU General Public License.
26//
27// This exception applies only to the code released under the name GNU
28// Common C++. If you copy code from other releases into a copy of GNU
29// Common C++, as the General Public License permits, the exception does
30// not apply to the code that you add in this way. To avoid misleading
31// anyone as to the status of such modified files, you must delete
32// this exception notice from them.
33//
34// If you write modifications of your own for GNU Common C++, it is your choice
35// whether to permit this exception to apply to your modifications.
36// If you do not wish that, delete this exception notice.
37//
38
39/**
40 * @file commoncpp/socket.h
41 * @short socket operations.
42 **/
43
44#ifndef COMMONCPP_SOCKET_H_
45#define COMMONCPP_SOCKET_H_
46
47#include <cstdio>
48
49#ifndef COMMONCPP_CONFIG_H_
50#include <commoncpp/config.h>
51#endif
52
53#ifndef COMMONCPP_STRING_H_
54#include <commoncpp/string.h>
55#endif
56
57#ifndef COMMONCPP_ADDRESS_H_
58#include <commoncpp/address.h>
59#endif
60
61#ifndef COMMONCPP_EXCEPTION_H_
62#include <commoncpp/exception.h>
63#endif
64
65#ifndef MSG_DONTWAIT
66#define MSG_DONTWAIT 0
67#endif
68
69#ifndef MSG_NOSIGNAL
70#define MSG_NOSIGNAL 0
71#endif
72
73#ifndef SOCK_DCCP
74#define SOCK_DCCP 6
75#endif
76#ifndef IPPROTO_DCCP
77#define IPPROTO_DCCP 33
78#endif
79#ifndef SOL_DCCP
80#define SOL_DCCP 269
81#endif
82#define DCCP_SOCKOPT_AVAILABLE_CCIDS 12
83#define DCCP_SOCKOPT_CCID 13
84#define DCCP_SOCKOPT_TX_CCID 14
85#define DCCP_SOCKOPT_RX_CCID 15
86
87NAMESPACE_COMMONCPP
88
89typedef socket_t SOCKET;
90
91class __EXPORT Socket : protected ucommon::Socket
92{
93public:
94 enum State {
95 INITIAL,
96 AVAILABLE,
97 BOUND,
98 CONNECTED,
99 CONNECTING,
100 STREAM
101 };
102 typedef enum State State;
103
104 enum Family {
105#ifdef CCXX_IPV6
106 IPV6 = AF_INET6,
107#endif
108 IPV4 = AF_INET
109 };
110
111 typedef enum Family Family;
112
113 enum Error {
114 errSuccess = 0,
115 errCreateFailed,
116 errCopyFailed,
117 errInput,
118 errInputInterrupt,
119 errResourceFailure,
120 errOutput,
121 errOutputInterrupt,
122 errNotConnected,
123 errConnectRefused,
124 errConnectRejected,
125 errConnectTimeout,
126 errConnectFailed,
127 errConnectInvalid,
128 errConnectBusy,
129 errConnectNoRoute,
130 errBindingFailed,
131 errBroadcastDenied,
132 errRoutingDenied,
133 errKeepaliveDenied,
134 errServiceDenied,
135 errServiceUnavailable,
136 errMulticastDisabled,
137 errTimeout,
138 errNoDelay,
139 errExtended,
140 errLookupFail,
141 errSearchErr,
142 errInvalidValue
143 };
144
145 typedef enum Error Error;
146
147 enum Tos {
148 tosLowDelay = 0,
149 tosThroughput,
150 tosReliability,
151 tosMinCost,
152 tosInvalid
153 };
154 typedef enum Tos Tos;
155
156 enum Pending {
157 pendingInput,
158 pendingOutput,
159 pendingError
160 };
161 typedef enum Pending Pending;
162
163private:
164 // used by exception handlers....
165 mutable Error errid;
166 mutable const char *errstr;
167 mutable long syserr;
168
169 void setSocket(void);
170
171protected:
172 static socket_t dupSocket(socket_t s,Socket::State state);
173
174 static Mutex mutex;
175
176 mutable struct {
177 bool thrown: 1;
178 bool broadcast: 1;
179 bool route: 1;
180 bool keepalive: 1;
181 bool loopback: 1;
182 bool multicast: 1;
183 bool completion: 1;
184 bool linger: 1;
185 unsigned ttl: 8;
186 } flags;
187
188 State volatile state;
189
190 /**
191 * This service is used to throw all socket errors which usually
192 * occur during the socket constructor.
193 *
194 * @param error defined socket error id.
195 * @param err string or message to pass.
196 * @param systemError the system error# that caused the error
197 */
198 Error error(Error error, const char *err = NULL, long systemError = 0) const;
199
200 /**
201 * This service is used to throw application defined socket errors
202 * where the application specific error code is a string.
203 *
204 * @param err string or message to pass.
205 */
206 inline void error(const char *err) const
207 {error(errExtended, err);};
208
209 /**
210 * This service is used to turn the error handler on or off for
211 * "throwing" exceptions by manipulating the thrown flag.
212 *
213 * @param enable true to enable handler.
214 */
215 inline void setError(bool enable)
216 {flags.thrown = !enable;};
217
218 /**
219 * Used as the default destructor for ending a socket. This
220 * will cleanly terminate the socket connection. It is provided
221 * for use in derived virtual destructors.
222 */
223 void endSocket(void);
224
225 /**
226 * Used as a common handler for connection failure processing.
227 *
228 * @return correct failure code to apply.
229 */
230 Error connectError(void);
231
232 /**
233 * Set the send limit.
234 */
235 Error sendLimit(int limit = 2048);
236
237 /**
238 * Set thr receive limit.
239 */
240 Error receiveLimit(int limit = 1);
241
242 /**
243 * Set the send timeout for sending raw network data.
244 *
245 * @return errSuccess if set.
246 * @param timer value in millisec.
247 */
248 Error sendTimeout(timeout_t timer);
249
250 /**
251 * Receive timeout for receiving raw network data.
252 *
253 * @return errSuccess if set.
254 * @param timer value in milliseconds.
255 */
256 Error receiveTimeout(timeout_t timer);
257
258 /**
259 * Set the protocol stack network kernel send buffer size
260 * associated with the socket.
261 *
262 * @return errSuccess on success, or error.
263 * @param size of buffer in bytes.
264 */
265 Error sendBuffer(unsigned size);
266
267 /**
268 * Set the protocol stack network kernel receive buffer size
269 * associated with the socket.
270 *
271 * @return errSuccess on success, or error.
272 * @param size of buffer in bytes.
273 */
274 Error receiveBuffer(unsigned size);
275
276 /**
277 * Set the total protocol stack network kernel buffer size
278 * for both send and receive together.
279 *
280 * @return errSuccess on success
281 * @param size of buffer.
282 */
283 Error bufferSize(unsigned size);
284
285 /**
286 * Set the subnet broadcast flag for the socket. This enables
287 * sending to a subnet and may require special image privileges
288 * depending on the operating system.
289 *
290 * @return 0 (errSuccess) on success, else error code.
291 * @param enable when set to true.
292 */
293 Error setBroadcast(bool enable);
294
295 /**
296 * Setting multicast binds the multicast interface used for
297 * the socket to the interface the socket itself has been
298 * implicitly bound to. It is also used as a check flag
299 * to make sure multicast is enabled before multicast
300 * operations are used.
301 *
302 * @return 0 (errSuccess) on success, else error code.
303 * @param enable when set to true.
304 * @param family of protocol.
305 */
306 Error setMulticastByFamily(bool enable, Family family = IPV4);
307
308 /**
309 * Set the multicast loopback flag for the socket. Loopback
310 * enables a socket to hear what it is sending.
311 *
312 * @return 0 (errSuccess) on success, else error code.
313 * @param enable when set to true.
314 * @param family of protocol.
315 */
316 Error setLoopbackByFamily(bool enable, Family family = IPV4);
317
318 /**
319 * Set the multicast time to live for a multicast socket.
320 *
321 * @return 0 (errSuccess) on success, else error code.
322 * @param ttl time to live.
323 * @param fam family of protocol.
324 */
325 Error setTimeToLiveByFamily(unsigned char ttl, Family fam = IPV4);
326
327 /**
328 * Join a multicast group.
329 *
330 * @return 0 (errSuccess) on success, else error code.
331 * @param ia address of multicast group to join.
332 */
333 Error join(const IPV4Multicast &ia);
334#ifdef CCXX_IPV6
335 Error join(const IPV6Multicast &ia);
336#endif
337
338 /**
339 * Drop membership from a multicast group.
340 *
341 * @return 0 (errSuccess) on success, else error code.
342 * @param ia address of multicast group to drop.
343 */
344 Error drop(const IPV4Multicast &ia);
345#ifdef CCXX_IPV6
346 Error drop(const IPV6Multicast &ia);
347#endif
348
349 /**
350 * Set the socket routing to indicate if outgoing messages
351 * should bypass normal routing (set false).
352 *
353 * @return 0 on success.
354 * @param enable normal routing when set to true.
355 */
356 Error setRouting(bool enable);
357
358 /**
359 * Enable/disable delaying packets (Nagle algorithm)
360 *
361 * @return 0 on success.
362 * @param enable disable Nagle algorithm when set to true.
363 */
364 Error setNoDelay(bool enable);
365
366 /**
367 * An unconnected socket may be created directly on the local
368 * machine. Sockets can occupy both the internet domain (AF_INET)
369 * and UNIX socket domain (AF_UNIX) under unix. The socket type
370 * (SOCK_STREAM, SOCK_DGRAM) and protocol may also be specified.
371 * If the socket cannot be created, an exception is thrown.
372 *
373 * @param domain socket domain to use.
374 * @param type base type and protocol family of the socket.
375 * @param protocol specific protocol to apply.
376 */
377 Socket(int domain, int type, int protocol = 0);
378
379 /**
380 * A socket object may be created from a file descriptor when that
381 * descriptor was created either through a socket() or accept()
382 * call. This constructor is mostly for internal use.
383 *
384 * @param fd file descriptor of an already existing socket.
385 */
386 Socket(socket_t fd);
387
388 /**
389 * Create an inactive socket object for base constructors.
390 */
391 Socket();
392
393 /**
394 * A socket can also be constructed from an already existing
395 * Socket object. On POSIX systems, the socket file descriptor
396 * is dup()'d. On Win32, DuplicateHandle() is used.
397 *
398 * @param source of existing socket to clone.
399 */
400 Socket(const Socket &source);
401
402 /**
403 * Process a logical input line from a socket descriptor
404 * directly.
405 *
406 * @param buf pointer to string.
407 * @param len maximum length to read.
408 * @param timeout for pending data in milliseconds.
409 * @return number of bytes actually read.
410 */
411 ssize_t readLine(char *buf, size_t len, timeout_t timeout = 0);
412
413 /**
414 * Read in a block of len bytes with specific separator. Can
415 * be zero, or any other char. If \\n or \\r, it's treated just
416 * like a readLine(). Otherwise it looks for the separator.
417 *
418 * @param buf pointer to byte allocation.
419 * @param len maximum length to read.
420 * @param separator separator for a particular ASCII character
421 * @param t timeout for pending data in milliseconds.
422 * @return number of bytes actually read.
423 */
424 virtual ssize_t readData(void * buf,size_t len,char separator=0,timeout_t t=0);
425
426 /**
427 * Write a block of len bytes to socket.
428 *
429 * @param buf pointer to byte allocation.
430 * @param len maximum length to write.
431 * @param t timeout for pending data in milliseconds.
432 * @return number of bytes actually written.
433 */
434 virtual ssize_t writeData(const void* buf,size_t len,timeout_t t=0);
435
436public:
437 ~Socket();
438
439 /**
440 * Often used by a "catch" to fetch the last error of a thrown
441 * socket.
442 *
443 * @return error number of Error error.
444 */
445 inline Error getErrorNumber(void) const {return errid;}
446
447 /**
448 * Often used by a "catch" to fetch the user set error string
449 * of a thrown socket, but only if EXTENDED error codes are used.
450 *
451 * @return string for error message.
452 */
453 inline const char *getErrorString(void) const {return errstr;}
454
455 inline long getSystemError(void) const {return syserr;}
456
457 const char *getSystemErrorString(void) const;
458
459 /**
460 * Get the status of pending operations. This can be used to
461 * examine if input or output is waiting, or if an error has
462 * occured on the descriptor.
463 *
464 * @return true if ready, false on timeout.
465 * @param pend ready check to perform.
466 * @param timeout in milliseconds, inf. if not specified.
467 */
468 virtual bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
469
470 /**
471 * See if a specific protocol family is available in the
472 * current runtime environment.
473 *
474 * @return true if family available.
475 */
476 static bool check(Family fam);
477
478 /**
479 * Operator based testing to see if a socket is currently
480 * active.
481 */
482 bool operator!() const;
483
484 operator bool() const;
485
486 /**
487 * Sockets may also be duplicated by the assignment operator.
488 */
489 Socket &operator=(const Socket &from);
490
491 /**
492 * May be used to examine the origin of data waiting in the
493 * socket receive queue. This can tell a TCP server where pending
494 * "connect" requests are coming from, or a UDP socket where it's
495 * next packet arrived from.
496 *
497 * @param port ptr to port number of sender.
498 * @return host address, test with "isInetAddress()".
499 */
500 virtual IPV4Host getIPV4Sender(tpport_t *port = NULL) const;
501
502 inline IPV4Host getSender(tpport_t *port = NULL) const
503 {return getIPV4Sender(port);}
504
505#ifdef CCXX_IPV6
506 virtual IPV6Host getIPV6Sender(tpport_t *port = NULL) const;
507#endif
508
509 /**
510 * Get the host address and port of the socket this socket
511 * is connected to. If the socket is currently not in a
512 * connected state, then a host address of 0.0.0.0 is
513 * returned.
514 *
515 * @param port ptr to port number of remote socket.
516 * @return host address of remote socket.
517 */
518 IPV4Host getIPV4Peer(tpport_t *port = NULL) const;
519
520 inline IPV4Host getPeer(tpport_t *port = NULL) const
521 {return getIPV4Peer(port);}
522
523#ifdef CCXX_IPV6
524 IPV6Host getIPV6Peer(tpport_t *port = NULL) const;
525#endif
526
527 /**
528 * Get the local address and port number this socket is
529 * currently bound to.
530 *
531 * @param port ptr to port number on local host.
532 * @return host address of interface this socket is bound to.
533 */
534 IPV4Host getIPV4Local(tpport_t *port = NULL) const;
535
536 inline IPV4Host getLocal(tpport_t *port = NULL) const
537 {return getIPV4Local(port);}
538
539#ifdef CCXX_IPV6
540 IPV6Host getIPV6Local(tpport_t *port = NULL) const;
541#endif
542
543 /**
544 * Used to specify blocking mode for the socket. A socket
545 * can be made non-blocking by setting setCompletion(false)
546 * or set to block on all access with setCompletion(true).
547 * I do not believe this form of non-blocking socket I/O is supported
548 * in winsock, though it provides an alternate asynchronous set of
549 * socket services.
550 *
551 * @param immediate mode specify socket I/O call blocking mode.
552 */
553 void setCompletion(bool immediate);
554
555 /**
556 * Enable lingering sockets on close.
557 *
558 * @param linger specify linger enable.
559 */
560 Error setLinger(bool linger);
561
562 /**
563 * Set the keep-alive status of this socket and if keep-alive
564 * messages will be sent.
565 *
566 * @return 0 on success.
567 * @param enable keep alive messages.
568 */
569 Error setKeepAlive(bool enable);
570
571 /**
572 * Set packet scheduling on platforms which support ip quality
573 * of service conventions. This effects how packets in the
574 * queue are scheduled through the interface.
575 *
576 * @return 0 on success, error code on failure.
577 * @param service type of service enumerated type.
578 */
579 Error setTypeOfService(Tos service);
580
581 /**
582 * Can test to see if this socket is "connected", and hence
583 * whether a "catch" can safely call getPeer(). Of course,
584 * an unconnected socket will return a 0.0.0.0 address from
585 * getPeer() as well.
586 *
587 * @return true when socket is connected to a peer.
588 */
589 bool isConnected(void) const;
590
591 /**
592 * Test to see if the socket is at least operating or if it
593 * is mearly initialized. "initialized" sockets may be the
594 * result of failed constructors.
595 *
596 * @return true if not in initial state.
597 */
598 bool isActive(void) const;
599
600 /**
601 * Return if broadcast has been enabled for the specified
602 * socket.
603 *
604 * @return true if broadcast socket.
605 */
606 inline bool isBroadcast(void) const
607 {return flags.broadcast;};
608
609 /**
610 * Return if socket routing is enabled.
611 *
612 * @return true if routing enabled.
613 */
614 inline bool isRouted(void) const
615 {return flags.route;};
616
617
618 inline struct in_addr getaddress(const IPV4Address &ia)
619 {return ia.getAddress();}
620
621#ifdef CCXX_IPV6
622 inline struct in6_addr getaddress(const IPV6Address &ia)
623 {return ia.getAddress();}
624#endif
625
626};
627
628#if defined(CCXX_EXCEPTIONS)
629
630class __EXPORT SockException : public IOException
631{
632private:
633 Socket::Error _socketError;
634
635public:
636 inline SockException(const String &str, Socket::Error socketError, long systemError = 0) :
637 IOException(str, systemError), _socketError(socketError) {};
638
639 inline Socket::Error getSocketError() const
640 { return _socketError; }
641};
642
643#endif
644
645END_NAMESPACE
646
647#endif