UCommon
socket.h
Go to the documentation of this file.
1 // Copyright (C) 1999-2005 Open Source Telecom Corporation.
2 // Copyright (C) 2006-2013 David Sugar, Tycho Softworks.
3 // Copyright (C) 2014 David Sugar, Tycho Softworks, Savoir-Faire Linux Inc.
4 // Copyright (C) 2015 Cherokees of Idaho, Savoir-Faire Linux Inc.
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 Lesser General Public License
17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 //
19 // As a special exception, you may use this file as part of a free software
20 // library without restriction. Specifically, if other files instantiate
21 // templates or use macros or inline functions from this file, or you compile
22 // this file and link it with other files to produce an executable, this
23 // file does not by itself cause the resulting executable to be covered by
24 // the GNU General Public License. This exception does not however
25 // invalidate any other reasons why the executable file might be covered by
26 // the GNU General Public License.
27 //
28 // This exception applies only to the code released under the name GNU
29 // Common C++. If you copy code from other releases into a copy of GNU
30 // Common C++, as the General Public License permits, the exception does
31 // not apply to the code that you add in this way. To avoid misleading
32 // anyone as to the status of such modified files, you must delete
33 // this exception notice from them.
34 //
35 // If you write modifications of your own for GNU Common C++, it is your choice
36 // whether to permit this exception to apply to your modifications.
37 // If you do not wish that, delete this exception notice.
38 //
39 
45 #ifndef COMMONCPP_SOCKET_H_
46 #define COMMONCPP_SOCKET_H_
47 
48 #include <cstdio>
49 
50 #ifndef COMMONCPP_CONFIG_H_
51 #include <commoncpp/config.h>
52 #endif
53 
54 #ifndef COMMONCPP_STRING_H_
55 #include <commoncpp/string.h>
56 #endif
57 
58 #ifndef COMMONCPP_ADDRESS_H_
59 #include <commoncpp/address.h>
60 #endif
61 
62 #ifndef COMMONCPP_EXCEPTION_H_
63 #include <commoncpp/exception.h>
64 #endif
65 
66 #ifndef MSG_DONTWAIT
67 #define MSG_DONTWAIT 0
68 #endif
69 
70 #ifndef MSG_NOSIGNAL
71 #define MSG_NOSIGNAL 0
72 #endif
73 
74 #ifndef SOCK_DCCP
75 #define SOCK_DCCP 6
76 #endif
77 #ifndef IPPROTO_DCCP
78 #define IPPROTO_DCCP 33
79 #endif
80 #ifndef SOL_DCCP
81 #define SOL_DCCP 269
82 #endif
83 #define DCCP_SOCKOPT_AVAILABLE_CCIDS 12
84 #define DCCP_SOCKOPT_CCID 13
85 #define DCCP_SOCKOPT_TX_CCID 14
86 #define DCCP_SOCKOPT_RX_CCID 15
87 
88 namespace ost {
89 
90 typedef socket_t SOCKET;
91 
92 class __EXPORT Socket : protected ucommon::Socket
93 {
94 public:
95  enum State {
96  INITIAL,
97  AVAILABLE,
98  BOUND,
99  CONNECTED,
100  CONNECTING,
101  STREAM
102  };
103  typedef enum State State;
104 
105  enum Family {
106 #ifdef CCXX_IPV6
107  IPV6 = AF_INET6,
108 #endif
109  IPV4 = AF_INET
110  };
111 
112  typedef enum Family Family;
113 
114  enum Error {
115  errSuccess = 0,
116  errCreateFailed,
117  errCopyFailed,
118  errInput,
119  errInputInterrupt,
120  errResourceFailure,
121  errOutput,
122  errOutputInterrupt,
123  errNotConnected,
124  errConnectRefused,
125  errConnectRejected,
126  errConnectTimeout,
127  errConnectFailed,
128  errConnectInvalid,
129  errConnectBusy,
130  errConnectNoRoute,
131  errBindingFailed,
132  errBroadcastDenied,
133  errRoutingDenied,
134  errKeepaliveDenied,
135  errServiceDenied,
136  errServiceUnavailable,
137  errMulticastDisabled,
138  errTimeout,
139  errNoDelay,
140  errExtended,
141  errLookupFail,
142  errSearchErr,
143  errInvalidValue
144  };
145 
146  typedef enum Error Error;
147 
148  enum Tos {
149  tosLowDelay = 0,
150  tosThroughput,
151  tosReliability,
152  tosMinCost,
153  tosInvalid
154  };
155  typedef enum Tos Tos;
156 
157  enum Pending {
158  pendingInput,
159  pendingOutput,
160  pendingError
161  };
162  typedef enum Pending Pending;
163 
164 private:
165  // used by exception handlers....
166  mutable Error errid;
167  mutable const char *errstr;
168  mutable long syserr;
169 
170  void setSocket(void);
171 
172 protected:
173  static socket_t dupSocket(socket_t s,Socket::State state);
174 
175  mutable struct {
176  bool thrown: 1;
177  bool broadcast: 1;
178  bool route: 1;
179  bool keepalive: 1;
180  bool loopback: 1;
181  bool multicast: 1;
182  bool completion: 1;
183  bool linger: 1;
184  unsigned ttl: 8;
185  } flags;
186 
187  State volatile state;
188 
197  Error error(Error error, const char *err = NULL, long systemError = 0) const;
198 
205  inline void error(const char *err) const {
206  error(errExtended, err);
207  }
208 
215  inline void setError(bool enable) {
216  flags.thrown = !enable;
217  }
218 
224  void endSocket(void);
225 
231  Error connectError(void) const;
232 
236  Error sendLimit(int limit = 2048);
237 
241  Error receiveLimit(int limit = 1);
242 
249  Error sendTimeout(timeout_t timer);
250 
257  Error receiveTimeout(timeout_t timer);
258 
266  Error sendBuffer(unsigned size);
267 
275  Error receiveBuffer(unsigned size);
276 
284  Error bufferSize(unsigned size);
285 
294  Error setBroadcast(bool enable);
295 
307  Error setMulticastByFamily(bool enable, Family family = IPV4);
308 
317  Error setLoopbackByFamily(bool enable, Family family = IPV4);
318 
326  Error setTimeToLiveByFamily(uint8_t ttl, Family fam = IPV4);
327 
334  Error join(const ucommon::Socket::address &ia, int iface = 0);
335  inline Error join(const IPV4Multicast &ia) {
336  return join(ucommon::Socket::address(getaddress(ia)));
337  }
338 #ifdef CCXX_IPV6
339  inline Error join(const IPV6Multicast &ia, int iface = 0) {
340  return join(ucommon::Socket::address(getaddress(ia)), iface);
341  }
342 #endif
343 
350  Error drop(const ucommon::Socket::address &ia, int iface = 0);
351  Error drop(const IPV4Multicast &ia) {
352  return drop(ucommon::Socket::address(getaddress(ia)));
353  }
354 #ifdef CCXX_IPV6
355  Error drop(const IPV6Multicast &ia, int iface = 0) {
356  return drop(ucommon::Socket::address(getaddress(ia)), iface);
357  }
358 #endif
359 
367  Error setRouting(bool enable);
368 
375  Error setNoDelay(bool enable);
376 
388  Socket(int domain, int type, int protocol = 0);
389 
397  Socket(socket_t fd);
398 
402  Socket();
403 
411  Socket(const Socket &source);
412 
422  ssize_t readLine(char *buf, size_t len, timeout_t timeout = 0);
423 
435  virtual ssize_t readData(void * buf,size_t len,char separator=0,timeout_t t=0);
436 
445  virtual ssize_t writeData(const void* buf,size_t len,timeout_t t=0);
446 
447 public:
448  ~Socket();
449 
456  inline Error getErrorNumber(void) const {
457  return errid;
458  }
459 
466  inline const char *getErrorString(void) const {
467  return errstr;
468  }
469 
470  inline long getSystemError(void) const {
471  return syserr;
472  }
473 
474  const char *getSystemErrorString(void) const;
475 
485  virtual bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
486 
493  static bool check(Family fam);
494 
499  bool operator!() const;
500 
501  operator bool() const;
502 
506  Socket &operator=(const Socket &from);
507 
517  ucommon::Socket::address getSender() const;
518 
519  virtual IPV4Host getIPV4Sender(in_port_t *port = NULL) const;
520 
521  inline IPV4Host getSender(in_port_t *port) const {
522  return getIPV4Sender(port);
523  }
524 
525 #ifdef CCXX_IPV6
526  virtual IPV6Host getIPV6Sender(in_port_t *port = NULL) const;
527 #endif
528 
538  ucommon::Socket::address getPeer() const;
539 
540  IPV4Host getIPV4Peer(in_port_t *port = NULL) const;
541 
542  inline IPV4Host getPeer(in_port_t *port) const {
543  return getIPV4Peer(port);
544  }
545 
546 #ifdef CCXX_IPV6
547  IPV6Host getIPV6Peer(in_port_t *port = NULL) const;
548 #endif
549 
557  IPV4Host getIPV4Local(in_port_t *port = NULL) const;
558 
559  inline IPV4Host getLocal(in_port_t *port) const {
560  return getIPV4Local(port);
561  }
562 
563 #ifdef CCXX_IPV6
564  IPV6Host getIPV6Local(in_port_t *port = NULL) const;
565 #endif
566 
567  ucommon::Socket::address getLocal() const;
568 
579  void setCompletion(bool immediate);
580 
586  Error setLinger(bool linger);
587 
595  Error setKeepAlive(bool enable);
596 
605  Error setTypeOfService(Tos service);
606 
615  bool isConnected(void) const;
616 
624  bool isActive(void) const;
625 
632  inline bool isBroadcast(void) const {
633  return flags.broadcast;
634  }
635 
641  inline bool isRouted(void) const {
642  return flags.route;
643  }
644 
645 
646  inline struct in_addr getaddress(const IPV4Address &ia) const {
647  return ia.getAddress();
648  }
649 
650 #ifdef CCXX_IPV6
651  inline struct in6_addr getaddress(const IPV6Address &ia) const {
652  return ia.getAddress();
653  }
654 #endif
655 
656 };
657 
658 #if defined(CCXX_EXCEPTIONS)
659 
660 class __EXPORT SockException : public IOException
661 {
662 private:
663  Socket::Error _socketError;
664 
665 public:
666  inline SockException(const String &str, Socket::Error socketError, long systemError = 0) :
667  IOException(str, systemError), _socketError(socketError) {}
668 
669  inline Socket::Error getSocketError() const {
670  return _socketError;
671  }
672 };
673 
674 #endif
675 
676 } // namespace ost
677 
678 #endif
Network addresses and sockets related classes.
AppLog & error(AppLog &sl)
Manipulator for error level.
Definition: applog.h:536
A generic socket address class.
Definition: socket.h:364
T &() limit(T &value, T &low, T &high)
Convenience macro to range restrict values.
Definition: generics.h:468
Common C++ generic string class.
GNU Common C++ exception model base classes.
A generic socket base class.
Definition: socket.h:327