ucommon
socket.h
Go to the documentation of this file.
1 // 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 
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_COMMONCPP
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  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 
198  Error error(Error error, const char *err = NULL, long systemError = 0) const;
199 
206  inline void error(const char *err) const
207  {error(errExtended, err);};
208 
215  inline void setError(bool enable)
216  {flags.thrown = !enable;};
217 
223  void endSocket(void);
224 
230  Error connectError(void);
231 
235  Error sendLimit(int limit = 2048);
236 
240  Error receiveLimit(int limit = 1);
241 
248  Error sendTimeout(timeout_t timer);
249 
256  Error receiveTimeout(timeout_t timer);
257 
265  Error sendBuffer(unsigned size);
266 
274  Error receiveBuffer(unsigned size);
275 
283  Error bufferSize(unsigned size);
284 
293  Error setBroadcast(bool enable);
294 
306  Error setMulticastByFamily(bool enable, Family family = IPV4);
307 
316  Error setLoopbackByFamily(bool enable, Family family = IPV4);
317 
325  Error setTimeToLiveByFamily(unsigned char ttl, Family fam = IPV4);
326 
333  Error join(const IPV4Multicast &ia);
334 #ifdef CCXX_IPV6
335  Error join(const IPV6Multicast &ia);
336 #endif
337 
344  Error drop(const IPV4Multicast &ia);
345 #ifdef CCXX_IPV6
346  Error drop(const IPV6Multicast &ia);
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  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 
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 
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 
553  void setCompletion(bool immediate);
554 
560  Error setLinger(bool linger);
561 
569  Error setKeepAlive(bool enable);
570 
579  Error setTypeOfService(Tos service);
580 
589  bool isConnected(void) const;
590 
598  bool isActive(void) const;
599 
606  inline bool isBroadcast(void) const
607  {return flags.broadcast;};
608 
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 
630 class __EXPORT SockException : public IOException
631 {
632 private:
633  Socket::Error _socketError;
634 
635 public:
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 
645 END_NAMESPACE
646 
647 #endif