ucommon
ucommon/socket.h
Go to the documentation of this file.
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