ucommon
|
00001 // Copyright (C) 1999-2005 Open Source Telecom Corporation. 00002 // Copyright (C) 2006-2010 David Sugar, Tycho Softworks. 00003 // 00004 // This program is free software; you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation; either version 2 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with this program; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 // 00018 // As a special exception, you may use this file as part of a free software 00019 // library without restriction. Specifically, if other files instantiate 00020 // templates or use macros or inline functions from this file, or you compile 00021 // this file and link it with other files to produce an executable, this 00022 // file does not by itself cause the resulting executable to be covered by 00023 // the GNU General Public License. This exception does not however 00024 // invalidate any other reasons why the executable file might be covered by 00025 // the GNU General Public License. 00026 // 00027 // This exception applies only to the code released under the name GNU 00028 // Common C++. If you copy code from other releases into a copy of GNU 00029 // Common C++, as the General Public License permits, the exception does 00030 // not apply to the code that you add in this way. To avoid misleading 00031 // anyone as to the status of such modified files, you must delete 00032 // this exception notice from them. 00033 // 00034 // If you write modifications of your own for GNU Common C++, it is your choice 00035 // whether to permit this exception to apply to your modifications. 00036 // If you do not wish that, delete this exception notice. 00037 // 00038 00044 #ifndef COMMONCPP_SOCKET_H_ 00045 #define COMMONCPP_SOCKET_H_ 00046 00047 #include <cstdio> 00048 00049 #ifndef COMMONCPP_CONFIG_H_ 00050 #include <commoncpp/config.h> 00051 #endif 00052 00053 #ifndef COMMONCPP_STRING_H_ 00054 #include <commoncpp/string.h> 00055 #endif 00056 00057 #ifndef COMMONCPP_ADDRESS_H_ 00058 #include <commoncpp/address.h> 00059 #endif 00060 00061 #ifndef COMMONCPP_EXCEPTION_H_ 00062 #include <commoncpp/exception.h> 00063 #endif 00064 00065 #ifndef MSG_DONTWAIT 00066 #define MSG_DONTWAIT 0 00067 #endif 00068 00069 #ifndef MSG_NOSIGNAL 00070 #define MSG_NOSIGNAL 0 00071 #endif 00072 00073 #ifndef SOCK_DCCP 00074 #define SOCK_DCCP 6 00075 #endif 00076 #ifndef IPPROTO_DCCP 00077 #define IPPROTO_DCCP 33 00078 #endif 00079 #ifndef SOL_DCCP 00080 #define SOL_DCCP 269 00081 #endif 00082 #define DCCP_SOCKOPT_AVAILABLE_CCIDS 12 00083 #define DCCP_SOCKOPT_CCID 13 00084 #define DCCP_SOCKOPT_TX_CCID 14 00085 #define DCCP_SOCKOPT_RX_CCID 15 00086 00087 NAMESPACE_COMMONCPP 00088 00089 typedef socket_t SOCKET; 00090 00091 class __EXPORT Socket : protected ucommon::Socket 00092 { 00093 public: 00094 enum State { 00095 INITIAL, 00096 AVAILABLE, 00097 BOUND, 00098 CONNECTED, 00099 CONNECTING, 00100 STREAM 00101 }; 00102 typedef enum State State; 00103 00104 enum Family { 00105 #ifdef CCXX_IPV6 00106 IPV6 = AF_INET6, 00107 #endif 00108 IPV4 = AF_INET 00109 }; 00110 00111 typedef enum Family Family; 00112 00113 enum Error { 00114 errSuccess = 0, 00115 errCreateFailed, 00116 errCopyFailed, 00117 errInput, 00118 errInputInterrupt, 00119 errResourceFailure, 00120 errOutput, 00121 errOutputInterrupt, 00122 errNotConnected, 00123 errConnectRefused, 00124 errConnectRejected, 00125 errConnectTimeout, 00126 errConnectFailed, 00127 errConnectInvalid, 00128 errConnectBusy, 00129 errConnectNoRoute, 00130 errBindingFailed, 00131 errBroadcastDenied, 00132 errRoutingDenied, 00133 errKeepaliveDenied, 00134 errServiceDenied, 00135 errServiceUnavailable, 00136 errMulticastDisabled, 00137 errTimeout, 00138 errNoDelay, 00139 errExtended, 00140 errLookupFail, 00141 errSearchErr, 00142 errInvalidValue 00143 }; 00144 00145 typedef enum Error Error; 00146 00147 enum Tos { 00148 tosLowDelay = 0, 00149 tosThroughput, 00150 tosReliability, 00151 tosMinCost, 00152 tosInvalid 00153 }; 00154 typedef enum Tos Tos; 00155 00156 enum Pending { 00157 pendingInput, 00158 pendingOutput, 00159 pendingError 00160 }; 00161 typedef enum Pending Pending; 00162 00163 private: 00164 // used by exception handlers.... 00165 mutable Error errid; 00166 mutable const char *errstr; 00167 mutable long syserr; 00168 00169 void setSocket(void); 00170 00171 protected: 00172 static socket_t dupSocket(socket_t s,Socket::State state); 00173 00174 static Mutex mutex; 00175 00176 mutable struct { 00177 bool thrown: 1; 00178 bool broadcast: 1; 00179 bool route: 1; 00180 bool keepalive: 1; 00181 bool loopback: 1; 00182 bool multicast: 1; 00183 bool completion: 1; 00184 bool linger: 1; 00185 unsigned ttl: 8; 00186 } flags; 00187 00188 State volatile state; 00189 00198 Error error(Error error, const char *err = NULL, long systemError = 0) const; 00199 00206 inline void error(const char *err) const 00207 {error(errExtended, err);}; 00208 00215 inline void setError(bool enable) 00216 {flags.thrown = !enable;}; 00217 00223 void endSocket(void); 00224 00230 Error connectError(void); 00231 00235 Error sendLimit(int limit = 2048); 00236 00240 Error receiveLimit(int limit = 1); 00241 00248 Error sendTimeout(timeout_t timer); 00249 00256 Error receiveTimeout(timeout_t timer); 00257 00265 Error sendBuffer(unsigned size); 00266 00274 Error receiveBuffer(unsigned size); 00275 00283 Error bufferSize(unsigned size); 00284 00293 Error setBroadcast(bool enable); 00294 00306 Error setMulticastByFamily(bool enable, Family family = IPV4); 00307 00316 Error setLoopbackByFamily(bool enable, Family family = IPV4); 00317 00325 Error setTimeToLiveByFamily(unsigned char ttl, Family fam = IPV4); 00326 00333 Error join(const IPV4Multicast &ia); 00334 #ifdef CCXX_IPV6 00335 Error join(const IPV6Multicast &ia); 00336 #endif 00337 00344 Error drop(const IPV4Multicast &ia); 00345 #ifdef CCXX_IPV6 00346 Error drop(const IPV6Multicast &ia); 00347 #endif 00348 00356 Error setRouting(bool enable); 00357 00364 Error setNoDelay(bool enable); 00365 00377 Socket(int domain, int type, int protocol = 0); 00378 00386 Socket(socket_t fd); 00387 00391 Socket(); 00392 00400 Socket(const Socket &source); 00401 00411 ssize_t readLine(char *buf, size_t len, timeout_t timeout = 0); 00412 00424 virtual ssize_t readData(void * buf,size_t len,char separator=0,timeout_t t=0); 00425 00434 virtual ssize_t writeData(const void* buf,size_t len,timeout_t t=0); 00435 00436 public: 00437 ~Socket(); 00438 00445 inline Error getErrorNumber(void) const {return errid;} 00446 00453 inline const char *getErrorString(void) const {return errstr;} 00454 00455 inline long getSystemError(void) const {return syserr;} 00456 00457 const char *getSystemErrorString(void) const; 00458 00468 virtual bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF); 00469 00476 static bool check(Family fam); 00477 00482 bool operator!() const; 00483 00484 operator bool() const; 00485 00489 Socket &operator=(const Socket &from); 00490 00500 virtual IPV4Host getIPV4Sender(tpport_t *port = NULL) const; 00501 00502 inline IPV4Host getSender(tpport_t *port = NULL) const 00503 {return getIPV4Sender(port);} 00504 00505 #ifdef CCXX_IPV6 00506 virtual IPV6Host getIPV6Sender(tpport_t *port = NULL) const; 00507 #endif 00508 00518 IPV4Host getIPV4Peer(tpport_t *port = NULL) const; 00519 00520 inline IPV4Host getPeer(tpport_t *port = NULL) const 00521 {return getIPV4Peer(port);} 00522 00523 #ifdef CCXX_IPV6 00524 IPV6Host getIPV6Peer(tpport_t *port = NULL) const; 00525 #endif 00526 00534 IPV4Host getIPV4Local(tpport_t *port = NULL) const; 00535 00536 inline IPV4Host getLocal(tpport_t *port = NULL) const 00537 {return getIPV4Local(port);} 00538 00539 #ifdef CCXX_IPV6 00540 IPV6Host getIPV6Local(tpport_t *port = NULL) const; 00541 #endif 00542 00553 void setCompletion(bool immediate); 00554 00560 Error setLinger(bool linger); 00561 00569 Error setKeepAlive(bool enable); 00570 00579 Error setTypeOfService(Tos service); 00580 00589 bool isConnected(void) const; 00590 00598 bool isActive(void) const; 00599 00606 inline bool isBroadcast(void) const 00607 {return flags.broadcast;}; 00608 00614 inline bool isRouted(void) const 00615 {return flags.route;}; 00616 00617 00618 inline struct in_addr getaddress(const IPV4Address &ia) 00619 {return ia.getAddress();} 00620 00621 #ifdef CCXX_IPV6 00622 inline struct in6_addr getaddress(const IPV6Address &ia) 00623 {return ia.getAddress();} 00624 #endif 00625 00626 }; 00627 00628 #if defined(CCXX_EXCEPTIONS) 00629 00630 class __EXPORT SockException : public IOException 00631 { 00632 private: 00633 Socket::Error _socketError; 00634 00635 public: 00636 inline SockException(const String &str, Socket::Error socketError, long systemError = 0) : 00637 IOException(str, systemError), _socketError(socketError) {}; 00638 00639 inline Socket::Error getSocketError() const 00640 { return _socketError; } 00641 }; 00642 00643 #endif 00644 00645 END_NAMESPACE 00646 00647 #endif