UCommon
|
00001 // Copyright (C) 2006-2010 David Sugar, Tycho Softworks. 00002 // 00003 // This file is part of GNU uCommon C++. 00004 // 00005 // GNU uCommon C++ is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU Lesser General Public License as published 00007 // by the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // GNU uCommon C++ 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 Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public License 00016 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>. 00017 00026 #ifndef _UCOMMON_SOCKET_H_ 00027 #define _UCOMMON_SOCKET_H_ 00028 00029 #ifndef _UCOMMON_TIMERS_H_ 00030 #include <ucommon/timers.h> 00031 #endif 00032 00033 #ifndef _UCOMMON_LINKED_H_ 00034 #include <ucommon/linked.h> 00035 #endif 00036 00037 #ifndef _UCOMMON_STRING_H_ 00038 #include <ucommon/string.h> 00039 #endif 00040 00041 extern "C" { 00042 struct addrinfo; 00043 } 00044 00045 #ifdef _MSWINDOWS_ 00046 #define SHUT_RDWR SD_BOTH 00047 #define SHUT_WR SD_SEND 00048 #define SHUT_RD SD_RECV 00049 #else 00050 #include <unistd.h> 00051 #include <sys/socket.h> 00052 #include <net/if.h> 00053 #include <netinet/in.h> 00054 #include <netdb.h> 00055 #endif 00056 00057 #include <errno.h> 00058 #include <stdio.h> 00059 00060 #ifndef IPTOS_LOWDELAY 00061 #define IPTOS_LOWDELAY 0x10 00062 #define IPTOS_THROUGHPUT 0x08 00063 #define IPTOS_RELIABILITY 0x04 00064 #define IPTOS_MINCOST 0x02 00065 #endif 00066 00067 #ifdef AF_UNSPEC 00068 #define DEFAULT_FAMILY AF_UNSPEC 00069 #else 00070 #define DEFAULT_FAMILY AF_INET 00071 #endif 00072 00073 struct sockaddr_internet; 00074 00075 typedef struct sockaddr *sockaddr_t; 00076 00080 typedef struct hostaddr_internet 00081 { 00082 union 00083 { 00084 struct in_addr ipv4; 00085 #ifdef AF_INET6 00086 struct in6_addr ipv6; 00087 #endif 00088 }; 00089 } inethostaddr_t; 00090 00091 #if defined(AF_INET6) || defined(__CYGWIN__) 00092 00099 typedef struct sockaddr_internet 00100 { 00101 union { 00102 #ifdef AF_INET6 00103 struct sockaddr_in6 ipv6; 00104 #endif 00105 struct sockaddr_in ipv4; 00106 struct sockaddr address; 00107 }; 00108 } inetsockaddr_t; 00109 #else 00110 typedef struct sockaddr_internet 00111 { 00112 union { 00113 struct sockaddr_in ipv4; 00114 struct sockaddr address; 00115 }; 00116 } inetsockaddr_t; 00117 00118 struct sockaddr_storage 00119 { 00120 #ifdef AF_UNIX 00121 char sa_data[128]; 00122 #else 00123 char sa_data[sizeof(struct sockaddr_in)]; 00124 #endif 00125 }; 00126 #endif 00127 00128 #ifndef SOCK_DCCP 00129 #define SOCK_DCCP 6 00130 #endif 00131 00132 #ifndef IPPROTO_DCCP 00133 #define IPPROTO_DCCP 23 00134 #endif 00135 00136 #ifndef SOL_DCCP 00137 #define SOL_DCCP 269 00138 #endif 00139 00140 #define DCCP_SOCKOPT_AVAILABLE_CCIDS 12 00141 #define DCCP_SOCKOPT_CCID 13 00142 #define DCCP_SOCKOPT_TX_CCID 14 00143 #define DCCP_SOCKOPT_RX_CCID 15 00144 00145 NAMESPACE_UCOMMON 00146 00156 class __EXPORT cidr : public LinkedObject 00157 { 00158 protected: 00159 int family; 00160 inethostaddr_t netmask, network; 00161 char name[16]; 00162 unsigned getMask(const char *cp) const; 00163 00164 public: 00168 typedef LinkedObject policy; 00169 00173 cidr(); 00174 00181 cidr(const char *string); 00182 00188 cidr(policy **policy, const char *string); 00189 00196 cidr(policy **policy, const char *string, const char *name); 00197 00202 cidr(const cidr& existing); 00203 00210 static cidr *find(policy *policy, const struct sockaddr *address); 00211 00219 static cidr *container(policy *policy, const struct sockaddr *address); 00220 00228 inline const char *getName(void) const 00229 {return name;}; 00230 00235 inline int getFamily(void) const 00236 {return family;}; 00237 00242 inline inethostaddr_t getNetwork(void) const 00243 {return network;}; 00244 00249 inline inethostaddr_t getNetmask(void) const 00250 {return netmask;}; 00251 00256 inethostaddr_t getBroadcast(void) const; 00257 00262 unsigned getMask(void) const; 00263 00268 void set(const char *string); 00269 00275 bool isMember(const struct sockaddr *address) const; 00276 00282 inline bool operator==(const struct sockaddr *address) const 00283 {return isMember(address);}; 00284 00290 inline bool operator!=(const struct sockaddr *address) const 00291 {return !isMember(address);}; 00292 }; 00293 00301 class __EXPORT Socket 00302 { 00303 protected: 00304 socket_t so; 00305 int ioerr; 00306 timeout_t iowait; 00307 00308 public: 00317 static struct addrinfo *getaddress(const char *host, const char *service, int type = SOCK_STREAM, int protocol = 0); 00318 00324 static void release(struct addrinfo *list); 00325 00331 typedef void *set_t; 00332 00333 static const size_t masksize; 00334 00343 class __EXPORT address 00344 { 00345 protected: 00346 struct addrinfo *list; 00347 00348 public: 00359 address(int family, const char *address, int type = SOCK_STREAM, int protocol = 0); 00360 00373 address(int family, const char *hostname, const char *service = NULL); 00374 00381 address(const char *host, const char *service, int type = SOCK_STREAM); 00382 00390 address(const char *hostname, unsigned service = 0); 00391 00395 address(); 00396 00401 address(const address& reference); 00402 00406 ~address(); 00407 00412 struct sockaddr *getAddr(void) const; 00413 00419 struct sockaddr *get(int family) const; 00420 00425 int getfamily(void) const; 00426 00431 struct sockaddr *find(struct sockaddr *addr) const; 00432 00437 inline struct addrinfo *getList(void) const 00438 {return list;}; 00439 00444 inline operator struct addrinfo *() const 00445 {return list;}; 00446 00451 inline struct addrinfo *operator*() const 00452 {return list;}; 00453 00458 inline operator bool() const 00459 {return list != NULL;}; 00460 00465 inline bool operator!() const 00466 {return list == NULL;}; 00467 00472 inline operator struct sockaddr *() const 00473 {return getAddr();}; 00474 00478 void clear(void); 00479 00486 void set(const char *hostname, const char *service = NULL, int type = SOCK_STREAM); 00487 00494 void add(const char *hostname, const char *service = NULL, int type = SOCK_STREAM); 00495 00503 void set(int family, const char *address, int type = SOCK_STREAM, int protocol = 0); 00504 00509 void add(sockaddr *address); 00510 00516 unsigned insert(struct addrinfo *address); 00517 00523 unsigned remove(struct addrinfo *address); 00524 00530 bool remove(struct sockaddr *address); 00531 00538 bool insert(struct sockaddr *address); 00539 00545 void copy(const struct addrinfo *address); 00546 00551 void set(struct sockaddr *address); 00552 00558 void set(const char *hostname, unsigned service = 0); 00559 00565 static struct sockaddr *dup(struct sockaddr *address); 00566 00572 static struct sockaddr_in *ipv4(struct sockaddr *address); 00573 00574 #ifdef AF_INET6 00575 00580 static struct sockaddr_in6 *ipv6(struct sockaddr *address); 00581 #endif 00582 }; 00583 00584 friend class address; 00585 00589 Socket(); 00590 00595 Socket(const Socket& existing); 00596 00601 Socket(socket_t socket); 00602 00608 Socket(struct addrinfo *address); 00609 00616 Socket(int family, int type, int protocol = 0); 00617 00627 Socket(const char *address, const char *port, int family = AF_UNSPEC, int type = 0, int protocol = 0); 00628 00632 virtual ~Socket(); 00633 00637 void cancel(void); 00638 00643 static void cancel(socket_t socket); 00644 00648 void release(void); 00649 00653 inline int err(void) const 00654 {return ioerr;} 00655 00661 bool isPending(unsigned value) const; 00662 00667 bool isConnected(void) const; 00668 00675 bool waitPending(timeout_t timeout = 0) const; 00676 00681 inline int nodelay(void) const 00682 {return nodelay(so);}; 00683 00691 static bool wait(socket_t socket, timeout_t timeout = 0); 00692 00699 bool waitSending(timeout_t timeout = 0) const; 00700 00705 inline unsigned getPending(void) const 00706 {return pending(so);}; 00707 00713 inline int broadcast(bool enable) 00714 {return broadcast(so, enable);}; 00715 00721 inline int keepalive(bool enable) 00722 {return keepalive(so, enable);}; 00723 00729 inline int blocking(bool enable) 00730 {return blocking(so, enable);}; 00731 00737 inline int multicast(unsigned ttl = 1) 00738 {return multicast(so, ttl);}; 00739 00745 inline int loopback(bool enable) 00746 {return loopback(so, enable);}; 00747 00752 inline int getError(void) 00753 {return error(so);}; 00754 00760 inline int ttl(unsigned char time) 00761 {return ttl(so, time);}; 00762 00768 inline int sendsize(unsigned size) 00769 {return sendsize(so, size);}; 00770 00776 inline int sendwait(unsigned size) 00777 {return sendwait(so, size);}; 00778 00779 00785 inline int recvsize(unsigned size) 00786 {return recvsize(so, size);}; 00787 00793 static int gettype(socket_t socket); 00794 00801 static unsigned segsize(socket_t socket, unsigned size = 0); 00802 00809 static bool setccid(socket_t socket, uint8_t ccid); 00810 00815 inline int gettype(void) 00816 {return gettype(so);}; 00817 00823 inline unsigned segsize(unsigned size) 00824 {return segsize(so, size);}; 00825 00831 inline bool setccid(uint8_t ccid) 00832 {return setccid(so, ccid);}; 00833 00842 inline int tos(int type) 00843 {return tos(so, type);}; 00844 00851 inline int priority(int scheduling) 00852 {return priority(so, scheduling);}; 00853 00857 inline void shutdown(void) 00858 {::shutdown(so, SHUT_RDWR);}; 00859 00867 int connectto(struct addrinfo *list); 00868 00875 int disconnect(void); 00876 00882 int join(struct addrinfo *list); 00883 00889 int drop(struct addrinfo *list); 00890 00896 int wait(timeout_t timeout = Timer::inf); 00897 00904 size_t peek(void *data, size_t number) const; 00905 00913 size_t readfrom(void *data, size_t number, struct sockaddr_storage *address = NULL); 00914 00922 size_t writeto(const void *data, size_t number, struct sockaddr *address = NULL); 00923 00936 size_t readline(char *data, size_t size); 00937 00943 size_t printf(const char *format, ...) __PRINTF(2,3); 00944 00956 size_t readline(string& buffer); 00957 00969 static ssize_t readline(socket_t socket, char *data, size_t size, timeout_t timeout = Timer::inf); 00970 00977 static ssize_t printf(socket_t socket, const char *format, ...) __PRINTF(2,3); 00978 00986 size_t writes(const char *string); 00987 00992 operator bool(); 00993 00998 bool operator!() const; 00999 01005 Socket& operator=(socket_t socket); 01006 01011 inline operator socket_t() const 01012 {return so;}; 01013 01018 inline socket_t operator*() const 01019 {return so;}; 01020 01027 static unsigned pending(socket_t socket); 01028 01035 static int sendsize(socket_t socket, unsigned size); 01036 01043 static int sendwait(socket_t socket, unsigned size); 01044 01051 static int recvsize(socket_t socket, unsigned size); 01052 01061 static int connectto(socket_t socket, struct addrinfo *list); 01062 01068 static int disconnect(socket_t socket); 01069 01076 static int drop(socket_t socket, struct addrinfo *list); 01077 01084 static int join(socket_t socket, struct addrinfo *list); 01085 01091 static int error(socket_t socket); 01092 01099 static int multicast(socket_t socket, unsigned ttl = 1); 01100 01107 static int loopback(socket_t socket, bool enable); 01108 01115 static int blocking(socket_t socket, bool enable); 01116 01123 static int keepalive(socket_t socket, bool enable); 01124 01131 static int broadcast(socket_t socket, bool enable); 01132 01138 static int nodelay(socket_t socket); 01139 01146 static int priority(socket_t socket, int scheduling); 01147 01154 static int tos(socket_t socket, int type); 01155 01162 static int ttl(socket_t socket, unsigned char time); 01163 01168 static int getfamily(socket_t socket); 01169 01175 inline static int getfamily(struct sockaddr_storage& address) 01176 {return ((struct sockaddr *)&address)->sa_family;}; 01177 01183 inline static int getfamily(struct sockaddr_internet& address) 01184 {return address.address.sa_family;}; 01185 01195 static ssize_t recvfrom(socket_t socket, void *buffer, size_t size, int flags = 0, struct sockaddr_storage *address = NULL); 01196 01206 static ssize_t sendto(socket_t socket, const void *buffer, size_t size, int flags = 0, struct sockaddr *address = NULL); 01207 01217 inline static ssize_t replyto(socket_t socket, const void *buffer, size_t size, int flags, struct sockaddr_storage *address) 01218 {return sendto(socket, buffer, size, flags, (struct sockaddr *)address);}; 01219 01229 inline static ssize_t sendinet(socket_t socket, const void *buffer, size_t size, int flags, struct sockaddr_internet *address) 01230 {return sendto(socket, buffer, size, flags, (struct sockaddr *)address);}; 01231 01241 static ssize_t recvinet(socket_t socket, void *buffer, size_t size, int flags = 0, struct sockaddr_internet *address = NULL); 01242 01251 static int bindto(socket_t socket, const char *address, const char *service, int protocol = 0); 01252 01260 static int listento(socket_t socket, struct sockaddr *address, int backlog = 5); 01261 01268 static int bindto(socket_t socket, struct sockaddr *address); 01269 01276 static socket_t acceptfrom(socket_t socket, struct sockaddr_storage *address = NULL); 01277 01285 static socket_t create(int family, int type, int protocol); 01286 01294 static socket_t create(struct addrinfo *address, int type, int protocol); 01295 01305 static socket_t create(const char *iface, const char *service, int family = AF_UNSPEC, int type = 0, int protocol = 0); 01306 01312 static socket_t create(Socket::address &address); 01313 01318 static void release(socket_t socket); 01319 01328 inline static size_t writeto(Socket& socket, const char *buffer, size_t size, struct sockaddr *address) 01329 {return socket.writeto(buffer, size, address);}; 01330 01339 inline static size_t readfrom(Socket& socket, char *buffer, size_t size, struct sockaddr_storage *address) 01340 {return socket.readfrom(buffer, size, address);}; 01341 01347 inline static void connectto(Socket& socket, Socket::address &address) 01348 {socket.connectto(address);}; 01349 01354 inline static void disconnect(Socket& socket) 01355 {socket.disconnect();}; 01356 01363 inline static Socket acceptfrom(Socket& socket, struct sockaddr_storage *address) 01364 {return Socket(acceptfrom(socket.so, address));}; 01365 01373 static char *gethostname(struct sockaddr *address, char *buffer, size_t size); 01374 01382 static struct addrinfo *gethint(socket_t socket, struct addrinfo *hint); 01383 01394 static socklen_t getaddr(socket_t socket, struct sockaddr_storage *address, const char *hostname, const char *service); 01395 01401 static socklen_t getlen(struct sockaddr *address); 01402 01410 static bool equal(struct sockaddr *address1, struct sockaddr *address2); 01411 01418 static unsigned copy(struct sockaddr *target, struct sockaddr *origin); 01419 01426 inline static unsigned store(struct sockaddr_storage *storage, struct sockaddr *address) 01427 {return copy((struct sockaddr*)storage, address);}; 01428 01435 static unsigned store(struct sockaddr_internet *storage, struct sockaddr *address); 01436 01444 static bool equalhost(struct sockaddr *address1, struct sockaddr *address2); 01445 01453 inline static bool equalfrom(struct sockaddr_storage *address1, struct sockaddr_storage *address2) 01454 {return equal((struct sockaddr *)address1, (struct sockaddr *)address2);}; 01455 01463 inline static bool equalinet(struct sockaddr_internet *address1, struct sockaddr_internet *address2) 01464 {return equal((struct sockaddr *)address1, (struct sockaddr *)address2);}; 01465 01473 static bool subnet(struct sockaddr *address1, struct sockaddr *address2); 01474 01482 static int getinterface(struct sockaddr *address, struct sockaddr *destination); 01483 01491 static char *getaddress(struct sockaddr *address, char *buffer, socklen_t size); 01492 01498 static short getservice(struct sockaddr *address); 01499 01505 inline static short inetservice(struct sockaddr_internet *address) 01506 {return getservice((struct sockaddr *)address);}; 01507 01514 static unsigned keyindex(struct sockaddr *address, unsigned size); 01515 01522 static unsigned keyhost(struct sockaddr *address, unsigned size); 01523 01527 static void init(void); 01528 01533 static void init(const char *program); 01534 01540 static void family(int query); 01541 01548 static void v4mapping(bool enable); 01549 01554 static int error(void); 01555 01564 static bool isNull(const char *string); 01565 01573 static bool isNumeric(const char *string); 01574 01583 static int getlocal(socket_t socket, struct sockaddr_storage *address); 01584 01593 static int getremote(socket_t socket, struct sockaddr_storage *address); 01594 01602 static int select(int max, set_t read, set_t write, set_t error); 01603 01612 static int select(int max, set_t read, set_t write, set_t error, timeout_t timeout); 01613 01618 static set_t getmask(void); 01619 01624 static void clear(set_t mask); 01625 01630 static void release(set_t mask); 01631 01637 static void set(socket_t socket, set_t mask); 01638 01644 static void clear(socket_t socket, set_t mask); 01645 01652 static bool test(socket_t socket, set_t mask); 01653 }; 01654 01660 class __EXPORT ListenSocket : protected Socket 01661 { 01662 public: 01672 ListenSocket(const char *address, const char *service, unsigned backlog = 5, int family = AF_UNSPEC, int type = 0, int protocol = 0); 01673 01684 static socket_t create(const char *address, const char *service, unsigned backlog = 5, int family = AF_UNSPEC, int type = 0, int protocol = 0); 01685 01691 socket_t accept(struct sockaddr_storage *address = NULL) const; 01692 01698 inline bool waitConnection(timeout_t timeout = Timer::inf) const 01699 {return Socket::waitPending(timeout);}; 01700 01705 inline operator socket_t() const 01706 {return so;}; 01707 01712 inline socket_t operator*() const 01713 {return so;}; 01714 01719 inline socket_t getsocket(void) const 01720 {return so;}; 01721 01722 }; 01723 01729 class __EXPORT TCPServer : public ListenSocket 01730 { 01731 public: 01739 TCPServer(const char *address, const char *service, unsigned backlog = 5); 01740 }; 01741 01745 __EXPORT struct addrinfo *_nextaddrinfo(struct addrinfo *addrinfo); 01746 01750 __EXPORT struct sockaddr *_getaddrinfo(struct addrinfo *addrinfo); 01751 01755 __EXPORT socket_t _getaddrsock(struct addrinfo *addrinfo); 01756 01762 template <> 01763 class linked_pointer<struct sockaddr> 01764 { 01765 private: 01766 struct addrinfo *ptr; 01767 01768 public: 01769 inline linked_pointer(struct addrinfo *list) 01770 {ptr = list;} 01771 01772 inline linked_pointer() 01773 {ptr = NULL;} 01774 01775 inline linked_pointer(Socket::address& list) 01776 {ptr = list.getList();}; 01777 01782 inline operator struct sockaddr *() const 01783 {return _getaddrinfo(ptr);}; 01784 01789 inline struct sockaddr *operator*() const 01790 {return _getaddrinfo(ptr);}; 01791 01792 inline operator struct sockaddr_in *() const 01793 {return (struct sockaddr_in *)_getaddrinfo(ptr);}; 01794 01795 inline struct sockaddr_in *in(void) const 01796 {return (struct sockaddr_in *)_getaddrinfo(ptr);}; 01797 01798 #ifdef AF_INET6 01799 inline operator struct sockaddr_in6 *() const 01800 {return (struct sockaddr_in6 *)_getaddrinfo(ptr);}; 01801 01802 inline struct sockaddr_in6 *in6(void) const 01803 {return (struct sockaddr_in6 *)_getaddrinfo(ptr);}; 01804 #endif 01805 01809 inline socket_t operator()(void) const 01810 {return _getaddrsock(ptr);}; 01811 01816 inline operator bool() const 01817 {return ptr != NULL;}; 01818 01823 inline void operator=(struct addrinfo *list) 01824 {ptr = list;}; 01825 01830 inline void operator=(Socket::address& list) 01831 {ptr = list.getList();}; 01832 01837 inline void set(struct addrinfo *list) 01838 {ptr = list;}; 01839 01844 inline void set(Socket::address& list) 01845 {ptr = list.getList();}; 01846 01847 01852 inline struct sockaddr* operator->() const 01853 {return _getaddrinfo(ptr);}; 01854 01859 inline bool operator!() const 01860 {return ptr == NULL;}; 01861 01862 inline void next(void) 01863 {ptr = _nextaddrinfo(ptr);}; 01864 }; 01865 01869 typedef Socket socket; 01870 01876 inline struct addrinfo *addrinfo(socket::address& address) 01877 {return address.getList();} 01878 01885 inline struct sockaddr *addr(socket::address& address) 01886 {return address.getAddr();} 01887 01895 inline bool eq(struct sockaddr *s1, struct sockaddr *s2) 01896 {return Socket::equal(s1, s2);} 01897 01905 inline bool eq(struct sockaddr_storage *s1, struct sockaddr_storage *s2) 01906 {return Socket::equal((struct sockaddr *)s1, (struct sockaddr *)s2);} 01907 01915 inline bool host_eq(struct sockaddr *s1, struct sockaddr *s2) 01916 {return Socket::equalhost(s1, s2);} 01917 01918 // to be depreciated... 01919 inline bool ieq(struct sockaddr *s1, struct sockaddr *s2) 01920 {return Socket::equalhost(s1, s2);} 01921 01922 String str(Socket& so, strsize_t size); 01923 01924 typedef TCPServer tcpserv_t; 01925 01926 01927 END_NAMESPACE 01928 01929 #endif