ucommon
|
00001 // Copyright (C) 1999-2005 Open Source Telecom Corporation. 00002 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks. 00003 // Copyright (C) 2014 Savoir-Faire Linux Inc. 00004 // 00005 // This program is free software; you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation; either version 2 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public License 00016 // along with this program. If not, see <http://www.gnu.org/licenses/>. 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 ost { 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 ucommon::Socket::address &ia, int iface = 0); 00334 inline Error join(const IPV4Multicast &ia) { return join(ucommon::Socket::address(getaddress(ia))); } 00335 #ifdef CCXX_IPV6 00336 inline Error join(const IPV6Multicast &ia, int iface = 0) { return join(ucommon::Socket::address(getaddress(ia)), iface); } 00337 #endif 00338 00345 Error drop(const ucommon::Socket::address &ia, int iface = 0); 00346 Error drop(const IPV4Multicast &ia) { return drop(ucommon::Socket::address(getaddress(ia))); } 00347 #ifdef CCXX_IPV6 00348 Error drop(const IPV6Multicast &ia, int iface = 0) { return drop(ucommon::Socket::address(getaddress(ia)), iface); } 00349 #endif 00350 00358 Error setRouting(bool enable); 00359 00366 Error setNoDelay(bool enable); 00367 00379 Socket(int domain, int type, int protocol = 0); 00380 00388 Socket(socket_t fd); 00389 00393 Socket(); 00394 00402 Socket(const Socket &source); 00403 00413 ssize_t readLine(char *buf, size_t len, timeout_t timeout = 0); 00414 00426 virtual ssize_t readData(void * buf,size_t len,char separator=0,timeout_t t=0); 00427 00436 virtual ssize_t writeData(const void* buf,size_t len,timeout_t t=0); 00437 00438 public: 00439 ~Socket(); 00440 00447 inline Error getErrorNumber(void) const {return errid;} 00448 00455 inline const char *getErrorString(void) const {return errstr;} 00456 00457 inline long getSystemError(void) const {return syserr;} 00458 00459 const char *getSystemErrorString(void) const; 00460 00470 virtual bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF); 00471 00478 static bool check(Family fam); 00479 00484 bool operator!() const; 00485 00486 operator bool() const; 00487 00491 Socket &operator=(const Socket &from); 00492 00502 ucommon::Socket::address getSender() const; 00503 00504 virtual IPV4Host getIPV4Sender(tpport_t *port = NULL) const; 00505 00506 inline IPV4Host getSender(tpport_t *port) const 00507 {return getIPV4Sender(port);} 00508 00509 #ifdef CCXX_IPV6 00510 virtual IPV6Host getIPV6Sender(tpport_t *port = NULL) const; 00511 #endif 00512 00522 ucommon::Socket::address getPeer() const; 00523 00524 IPV4Host getIPV4Peer(tpport_t *port = NULL) const; 00525 00526 inline IPV4Host getPeer(tpport_t *port) const 00527 {return getIPV4Peer(port);} 00528 00529 #ifdef CCXX_IPV6 00530 IPV6Host getIPV6Peer(tpport_t *port = NULL) const; 00531 #endif 00532 00540 IPV4Host getIPV4Local(tpport_t *port = NULL) const; 00541 00542 inline IPV4Host getLocal(tpport_t *port) const 00543 {return getIPV4Local(port);} 00544 00545 #ifdef CCXX_IPV6 00546 IPV6Host getIPV6Local(tpport_t *port = NULL) const; 00547 #endif 00548 00549 ucommon::Socket::address getLocal() const; 00550 00561 void setCompletion(bool immediate); 00562 00568 Error setLinger(bool linger); 00569 00577 Error setKeepAlive(bool enable); 00578 00587 Error setTypeOfService(Tos service); 00588 00597 bool isConnected(void) const; 00598 00606 bool isActive(void) const; 00607 00614 inline bool isBroadcast(void) const 00615 {return flags.broadcast;} 00616 00622 inline bool isRouted(void) const 00623 {return flags.route;} 00624 00625 00626 inline struct in_addr getaddress(const IPV4Address &ia) 00627 {return ia.getAddress();} 00628 00629 #ifdef CCXX_IPV6 00630 inline struct in6_addr getaddress(const IPV6Address &ia) 00631 {return ia.getAddress();} 00632 #endif 00633 00634 }; 00635 00636 #if defined(CCXX_EXCEPTIONS) 00637 00638 class __EXPORT SockException : public IOException 00639 { 00640 private: 00641 Socket::Error _socketError; 00642 00643 public: 00644 inline SockException(const String &str, Socket::Error socketError, long systemError = 0) : 00645 IOException(str, systemError), _socketError(socketError) {} 00646 00647 inline Socket::Error getSocketError() const 00648 {return _socketError;} 00649 }; 00650 00651 #endif 00652 00653 } // namespace ost 00654 00655 #endif