ucommon
socket.h
Go to the documentation of this file.
1 // Copyright (C) 1999-2005 Open Source Telecom Corporation.
2 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
3 // Copyright (C) 2014 Savoir-Faire Linux Inc.
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with this program. If not, see <http://www.gnu.org/licenses/>.
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 
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 
87 namespace ost {
88 
89 typedef socket_t SOCKET;
90 
91 class __EXPORT Socket : protected ucommon::Socket
92 {
93 public:
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 
163 private:
164  // used by exception handlers....
165  mutable Error errid;
166  mutable const char *errstr;
167  mutable long syserr;
168 
169  void setSocket(void);
170 
171 protected:
172  static socket_t dupSocket(socket_t s,Socket::State state);
173 
174  mutable struct {
175  bool thrown: 1;
176  bool broadcast: 1;
177  bool route: 1;
178  bool keepalive: 1;
179  bool loopback: 1;
180  bool multicast: 1;
181  bool completion: 1;
182  bool linger: 1;
183  unsigned ttl: 8;
184  } flags;
185 
186  State volatile state;
187 
196  Error error(Error error, const char *err = NULL, long systemError = 0) const;
197 
204  inline void error(const char *err) const
205  {error(errExtended, err);}
206 
213  inline void setError(bool enable)
214  {flags.thrown = !enable;}
215 
221  void endSocket(void);
222 
228  Error connectError(void);
229 
233  Error sendLimit(int limit = 2048);
234 
238  Error receiveLimit(int limit = 1);
239 
246  Error sendTimeout(timeout_t timer);
247 
254  Error receiveTimeout(timeout_t timer);
255 
263  Error sendBuffer(unsigned size);
264 
272  Error receiveBuffer(unsigned size);
273 
281  Error bufferSize(unsigned size);
282 
291  Error setBroadcast(bool enable);
292 
304  Error setMulticastByFamily(bool enable, Family family = IPV4);
305 
314  Error setLoopbackByFamily(bool enable, Family family = IPV4);
315 
323  Error setTimeToLiveByFamily(unsigned char ttl, Family fam = IPV4);
324 
331  Error join(const ucommon::Socket::address &ia, int iface = 0);
332  inline Error join(const IPV4Multicast &ia) { return join(ucommon::Socket::address(getaddress(ia))); }
333 #ifdef CCXX_IPV6
334  inline Error join(const IPV6Multicast &ia, int iface = 0) { return join(ucommon::Socket::address(getaddress(ia)), iface); }
335 #endif
336 
343  Error drop(const ucommon::Socket::address &ia, int iface = 0);
344  Error drop(const IPV4Multicast &ia) { return drop(ucommon::Socket::address(getaddress(ia))); }
345 #ifdef CCXX_IPV6
346  Error drop(const IPV6Multicast &ia, int iface = 0) { return drop(ucommon::Socket::address(getaddress(ia)), iface); }
347 #endif
348 
356  Error setRouting(bool enable);
357 
364  Error setNoDelay(bool enable);
365 
377  Socket(int domain, int type, int protocol = 0);
378 
386  Socket(socket_t fd);
387 
391  Socket();
392 
400  Socket(const Socket &source);
401 
411  ssize_t readLine(char *buf, size_t len, timeout_t timeout = 0);
412 
424  virtual ssize_t readData(void * buf,size_t len,char separator=0,timeout_t t=0);
425 
434  virtual ssize_t writeData(const void* buf,size_t len,timeout_t t=0);
435 
436 public:
437  ~Socket();
438 
445  inline Error getErrorNumber(void) const {return errid;}
446 
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 
468  virtual bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
469 
476  static bool check(Family fam);
477 
482  bool operator!() const;
483 
484  operator bool() const;
485 
489  Socket &operator=(const Socket &from);
490 
500  ucommon::Socket::address getSender() const;
501 
502  virtual IPV4Host getIPV4Sender(tpport_t *port = NULL) const;
503 
504  inline IPV4Host getSender(tpport_t *port) const
505  {return getIPV4Sender(port);}
506 
507 #ifdef CCXX_IPV6
508  virtual IPV6Host getIPV6Sender(tpport_t *port = NULL) const;
509 #endif
510 
520  ucommon::Socket::address getPeer() const;
521 
522  IPV4Host getIPV4Peer(tpport_t *port = NULL) const;
523 
524  inline IPV4Host getPeer(tpport_t *port) const
525  {return getIPV4Peer(port);}
526 
527 #ifdef CCXX_IPV6
528  IPV6Host getIPV6Peer(tpport_t *port = NULL) const;
529 #endif
530 
538  IPV4Host getIPV4Local(tpport_t *port = NULL) const;
539 
540  inline IPV4Host getLocal(tpport_t *port) const
541  {return getIPV4Local(port);}
542 
543 #ifdef CCXX_IPV6
544  IPV6Host getIPV6Local(tpport_t *port = NULL) const;
545 #endif
546 
547  ucommon::Socket::address getLocal() const;
548 
559  void setCompletion(bool immediate);
560 
566  Error setLinger(bool linger);
567 
575  Error setKeepAlive(bool enable);
576 
585  Error setTypeOfService(Tos service);
586 
595  bool isConnected(void) const;
596 
604  bool isActive(void) const;
605 
612  inline bool isBroadcast(void) const
613  {return flags.broadcast;}
614 
620  inline bool isRouted(void) const
621  {return flags.route;}
622 
623 
624  inline struct in_addr getaddress(const IPV4Address &ia)
625  {return ia.getAddress();}
626 
627 #ifdef CCXX_IPV6
628  inline struct in6_addr getaddress(const IPV6Address &ia)
629  {return ia.getAddress();}
630 #endif
631 
632 };
633 
634 #if defined(CCXX_EXCEPTIONS)
635 
636 class __EXPORT SockException : public IOException
637 {
638 private:
639  Socket::Error _socketError;
640 
641 public:
642  inline SockException(const String &str, Socket::Error socketError, long systemError = 0) :
643  IOException(str, systemError), _socketError(socketError) {}
644 
645  inline Socket::Error getSocketError() const
646  {return _socketError;}
647 };
648 
649 #endif
650 
651 } // namespace ost
652 
653 #endif
T &() limit(T &value, T &low, T &high)
Convenience macro to range restrict values.
Definition: generics.h:565
A generic socket base class.
Definition: socket.h:316
Definition: address.h:58
Network addresses and sockets related classes.
Common C++ generic string class.
A generic socket address class.
Definition: socket.h:349
unsigned long timeout_t
Typedef for millisecond timer values.
Definition: platform.h:334
GNU Common C++ exception model base classes.