1 // Copyright (C) 1999-2005 Open Source Telecom Corporation.
2 // Copyright (C) 2009 Leandro Melo de Sales <leandroal@gmail.com>
3 // Copyright (C) 2006-2010 David Sugar, Tycho Softworks,
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 //
19 // As a special exception, you may use this file as part of a free software
20 // library without restriction. Specifically, if other files instantiate
21 // templates or use macros or inline functions from this file, or you compile
22 // this file and link it with other files to produce an executable, this
23 // file does not by itself cause the resulting executable to be covered by
24 // the GNU General Public License. This exception does not however
25 // invalidate any other reasons why the executable file might be covered by
26 // the GNU General Public License.
27 //
28 // This exception applies only to the code released under the name GNU
29 // Common C++. If you copy code from other releases into a copy of GNU
30 // Common C++, as the General Public License permits, the exception does
31 // not apply to the code that you add in this way. To avoid misleading
32 // anyone as to the status of such modified files, you must delete
33 // this exception notice from them.
34 //
35 // If you write modifications of your own for GNU Common C++, it is your choice
36 // whether to permit this exception to apply to your modifications.
37 // If you do not wish that, delete this exception notice.
38 //
39
45 #ifndef CCXX_SOCKET_H_
46 #define CCXX_SOCKET_H_
47
48 #ifndef CCXX_ADDRESS_H_
50 #endif
51
52 #if defined(WIN32) && !defined(__CYGWIN32__)
53 #include <io.h>
54 #define _IOLEN64 (unsigned)
55 #define _IORET64 (int)
56 #define TIMEOUT_INF ~((timeout_t) 0)
57 typedef int socklen_t;
58 #else
59 #define INVALID_SOCKET -1
61 #endif
62
63 #ifndef _IOLEN64
65 #endif
66
67 #ifndef _IORET64
69 #endif
70
71 #ifndef MSG_DONTWAIT
72 #define MSG_DONTWAIT 0
73 #endif
74
75 #ifndef MSG_NOSIGNAL
76 #define MSG_NOSIGNAL 0
77 #endif
78
79 #ifndef SOCK_DCCP
81 #endif
82 #ifndef IPPROTO_DCCP
83 #define IPPROTO_DCCP 33
84 #endif
85 #ifndef SOL_DCCP
87 #endif
88 #define DCCP_SOCKOPT_AVAILABLE_CCIDS 12
89 #define DCCP_SOCKOPT_CCID 13
90 #define DCCP_SOCKOPT_TX_CCID 14
91 #define DCCP_SOCKOPT_RX_CCID 15
92
93 #ifdef CCXX_NAMESPACES
94 namespace ost {
95 #endif
96
101
120 {
121 public:
123 #ifdef CCXX_IPV6
124 IPV6 = AF_INET6,
125 #endif
127 };
128
130
161 };
162
164
171 };
173
178 };
180
181 protected:
189 };
191
192 private:
193 // used by exception handlers....
197
198 void setSocket(void);
200
201 protected:
203
204 mutable struct {
214 } flags;
215
223
233
240 inline void error(
const char *err)
const
241 {
error(errExtended, err);};
242
250 {flags.thrown = !enable;};
251
257 void endSocket(void);
258
264 Error connectError(void);
265
269 Error sendLimit(int limit = 2048);
270
274 Error receiveLimit(int limit = 1);
275
283
291
299 Error sendBuffer(unsigned size);
300
308 Error receiveBuffer(unsigned size);
309
317 Error bufferSize(unsigned size);
318
327 Error setBroadcast(bool enable);
328
340 Error setMulticastByFamily(bool enable, Family family = IPV4);
341
350 Error setLoopbackByFamily(bool enable, Family family = IPV4);
351
359 Error setTimeToLiveByFamily(unsigned char ttl, Family fam = IPV4);
360
368 #ifdef CCXX_IPV6
369 Error join(const IPV6Multicast &ia);
370 #endif
371
379 #ifdef CCXX_IPV6
380 Error drop(const IPV6Multicast &ia);
381 #endif
382
390 Error setRouting(bool enable);
391
392
399 Error setNoDelay(bool enable);
400
412 Socket(
int domain,
int type,
int protocol = 0);
413
422
427
436
446 ssize_t readLine(
char *buf,
size_t len,
timeout_t timeout = 0);
447
459 virtual ssize_t readData(
void * buf,
size_t len,
char separator=0,
timeout_t t=0);
460
469 virtual ssize_t writeData(
const void* buf,
size_t len,
timeout_t t=0);
470
471 public:
480
487 static bool check(Family fam);
488
493
504
506 {return getIPV4Sender(port);}
507
508 #ifdef CCXX_IPV6
509 virtual IPV6Host getIPV6Sender(
tpport_t *port = NULL)
const;
510 #endif
511
522
524 {return getIPV4Peer(port);}
525
526 #ifdef CCXX_IPV6
527 IPV6Host getIPV6Peer(
tpport_t *port = NULL)
const;
528 #endif
529
538
540 {return getIPV4Local(port);}
541
542 #ifdef CCXX_IPV6
543 IPV6Host getIPV6Local(
tpport_t *port = NULL)
const;
544 #endif
545
574
576 {return getIPV4NAT(port);}
577
578 #ifdef CCXX_IPV6
579 IPV6Host getIPV6NAT(
tpport_t *port = NULL)
const;
580 #endif
581
592 void setCompletion(bool immediate);
593
599 Error setLinger(bool linger);
600
608 Error setKeepAlive(bool enable);
609
618 Error setTypeOfService(Tos service);
619
628 bool isConnected(void) const;
629
637 bool isActive(void) const;
638
643 bool operator!() const;
644
652 {return flags.broadcast;};
653
660 {return flags.route;};
661
669
677
679
680 const char *getSystemErrorString(void) const;
681
692 };
693
721 {
722 union {
723 struct sockaddr_in ipv4;
724 #ifdef CCXX_IPV6
725 struct sockaddr_in6 ipv6;
726 #endif
727 } peer;
728
730
731 public:
744 #ifdef CCXX_IPV6
745 virtual bool onAccept(
const IPV6Host &ia,
tpport_t port);
746 #endif
747
749
750 #ifdef CCXX_IPV6
751 virtual IPV6Host getIPV6Sender(
tpport_t *port = NULL)
const;
752 #endif
753
766 #ifdef CCXX_IPV6
768 #endif
769
780
785
790
794 void reject(void);
795
799 void disconnect(void);
800
804 bool setCCID(uint8 ccid);
805
809 int getTxCCID();
810
814 int getRxCCID();
815
819 size_t available();
820
829 #ifdef CCXX_IPV6
831 #endif
832
836 void connect(const char *name);
837
845
850 };
851
885 {
886 private:
889
890 protected:
891 #ifdef CCXX_IPV6
892 union {
893 struct sockaddr_in6 ipv6;
894 struct sockaddr_in ipv4;
895 } peer;
896 #else
897 union {
898 struct sockaddr_in ipv4;
899 } peer;
900 #endif
901
903
904 public:
909
914
925 #ifdef CCXX_IPV6
927 #endif
928
933
939
945
951
961 #ifdef CCXX_IPV6
962 void setPeer(
const IPV6Host &host,
tpport_t port);
963 void connect(
const IPV6Host &host,
tpport_t port);
964 #endif
965
973 Socket::Error getInterfaceIndex(
const char *ethX,
int& InterfaceIndex);
974
984
985
993 ssize_t send(const void *buf, size_t len);
994
1003 ssize_t receive(void *buf, size_t len, bool reply = false);
1004
1015 {return getIPV4Peer(port);}
1016
1017 #ifdef CCXX_IPV6
1018 IPV6Host getIPV6Peer(
tpport_t *port = NULL)
const;
1019 #endif
1020
1028 inline ssize_t
peek(
void *buf,
size_t len)
1029 {
return _IORET64 ::recv(so, (
char *)buf,
_IOLEN64 len, MSG_PEEK);};
1030
1034 void setPeer(const char *service);
1035 void connect(const char *service);
1036
1041 Error disconnect(void);
1042 };
1043
1044
1054 {
1055 private:
1057
1060
1061 public:
1069
1077 };
1078
1088 {
1089 private:
1098
1099 protected:
1104
1117 #ifdef CCXX_IPV6
1119 #endif
1120
1131 #ifdef CCXX_IPV6
1133 #endif
1134
1145
1154 #ifdef CCXX_IPV6
1156 #endif
1157
1165 inline ssize_t
send(
const void *buf,
size_t len)
1167
1173
1174 /*
1175 * Get transmitter socket.
1176 *
1177 * @return transmitter.
1178 */
1180 {return so;};
1181
1184
1187
1188 public:
1198 inline ssize_t
transmit(
const char *buffer,
size_t len)
1200
1209
1210
1213
1216
1219 };
1220
1230 {
1231 protected:
1243 #ifdef CCXX_IPV6
1245 #endif
1246
1257 #ifdef CCXX_IPV6
1259 #endif
1260
1269
1275
1277 {return so;};
1278
1281
1284
1287
1288 #ifdef CCXX_IPV6
1289 inline Error join(const IPV6Multicast &ia)
1291 #endif
1292
1295
1296 #ifdef CCXX_IPV6
1297 inline Error drop(const IPV6Multicast &ia)
1299 #endif
1300
1301 public:
1310 {
return _IORET64 ::recv(so, (
char *)buf,
_IOLEN64 len, 0);};
1311
1320 };
1321
1333 {
1334 public:
1343 #ifdef CCXX_IPV6
1345 #endif
1346
1357 #ifdef CCXX_IPV6
1359 #endif
1360
1367 Error disconnect(
void);
1368 };
1369
1370
1396 {
1397 protected:
1399 void setSegmentSize(unsigned mss);
1400
1401 public:
1414
1419 {return so;};
1420
1425 {return segsize;};
1426
1440
1451 TCPSocket(
const char *name,
unsigned backlog = 5,
unsigned mss = 536);
1452
1463
1467 void reject(void);
1468
1474
1482
1487 };
1488
1489 #ifdef CCXX_IPV6
1490
1515 {
1516 private:
1517 int segsize;
1518 void setSegmentSize(unsigned mss);
1519
1520 public:
1532 virtual bool onAccept(
const IPV6Host &ia,
tpport_t port);
1533
1537 inline SOCKET getSocket(
void)
1538 {return so;};
1539
1540 inline int getSegmentSize(void)
1541 {return segsize;};
1542
1555 TCPV6Socket(
const IPV6Address &bind,
tpport_t port,
unsigned backlog = 5,
unsigned mss = 536);
1556
1567 TCPV6Socket(const char *name, unsigned backlog = 5, unsigned mss = 536);
1568
1577 inline IPV6Host getRequest(
tpport_t *port = NULL)
const
1578 {return Socket::getIPV6Sender(port);}
1579
1583 void reject(void);
1584
1588 inline IPV6Host getLocal(
tpport_t *port = NULL)
const
1589 {return Socket::getIPV6Local(port);}
1590
1598
1602 virtual ~TCPV6Socket();
1603 };
1604
1605 #endif
1606
1607 /*
1608 :\projects\libraries\cplusplus\commonc++\win32\socket.h(357) : warning C4275: non dll-interface class 'streambuf' used as base for dll-interface class 'TCPStream'
1609 c:\program files\microsoft visual studio\vc98\include\streamb.h(69) : see declaration of 'streambuf'
1610 c:\projects\libraries\cplusplus\commonc++\win32\socket.h(358) : warning C4275: non dll-interface class 'iostream' used as base for dll-interface class 'TCPStream'
1611 c:\program files\microsoft visual studio\vc98\include\iostream.h(66) : see declaration of 'iostream'
1612 */
1613
1614 #ifdef _MSC_VER
1615 #pragma warning(disable:4275) // disable C4275 warning
1616 #endif
1617
1632 {
1633 private:
1634 int doallocate();
1635
1636 void segmentBuffering(unsigned mss);
1637
1640
1641 protected:
1646
1647 public:
1653
1657 void disconnect(void);
1658
1662 int getSegmentSize(void);
1663
1664 protected:
1671 void allocate(size_t size);
1672
1677 void endStream(void);
1678
1685 int underflow();
1686
1695 int uflow();
1696
1704 int overflow(int ch);
1705
1715 #ifdef CCXX_IPV6
1716 void connect(
const IPV6Host &host,
tpport_t port,
unsigned mss = 536);
1717 #endif
1718
1726 void connect(const char *name, unsigned mss = 536);
1727
1736 {return ((std::iostream *)this);};
1737
1738 public:
1749 #ifdef CCXX_IPV6
1751 #endif
1752
1759 #ifdef CCXX_IPV6
1760 void connect(TCPV6Socket &server);
1761 #endif
1762
1774 #ifdef CCXX_IPV6
1776 #endif
1777
1787 TCPStream(
const char *name, Family family = IPV4,
unsigned mss = 536,
bool throwflag =
false,
timeout_t timer = 0);
1788
1795 {timeout = timer;};
1796
1804
1810
1817 int sync(void);
1818
1819 #ifdef HAVE_SNPRINTF
1820
1826 size_t printf(const char *format, ...);
1827 #endif
1828
1837
1845 inline ssize_t
peek(
void *buf,
size_t len)
1846 {
return _IORET64 ::recv(so, (
char *)buf,
_IOLEN64 len, MSG_PEEK);};
1847
1854 {return bufsize;};
1855 };
1856
1868 {
1869 private:
1871 protected:
1885
1892 void initial(void);
1893
1894 public:
1906 tpport_t port,
size_t size = 536,
int pri = 0,
size_t stack = 0);
1907 #ifdef CCXX_IPV6
1909 tpport_t port,
size_t size = 536,
int pri = 0,
size_t stack = 0);
1910 #endif
1911
1922 #ifdef CCXX_IPV6
1923 TCPSession(TCPV6Socket &server,
int pri = 0,
size_t stack = 0);
1924 #endif
1925
1930 };
1931
1932 #if defined(WIN32)
1933
1943 class init_WSA
1944 {
1945 public:
1946 init_WSA();
1947 ~init_WSA();
1948 };
1949
1950 #endif // WIN32
1951
1953
1966 {
1967 private:
1968
1970
1971 protected:
1977
1982 void endStream(void);
1983
1993
1994
1995 public:
2005
2015
2022
2028
2041
2043
2055 ssize_t read(
char *bytes,
size_t length,
timeout_t timeout = 0);
2056
2068 ssize_t write(
const char *bytes,
size_t length,
timeout_t timeout = 0);
2069
2083 ssize_t peek(
char *bytes,
size_t length,
timeout_t timeout = 0);
2084
2085 };
2086
2087 #ifdef COMMON_STD_EXCEPTION
2088 class __EXPORT SockException :
public IOException
2089 {
2090 private:
2092
2093 public:
2095 IOException(str, systemError), _socketError(socketError) {};
2096
2098 { return _socketError; }
2099 };
2100 #endif
2101
2102 #ifdef CCXX_NAMESPACES
2103 }
2104 #endif
2105
2106 #endif
2107
const char * getErrorString(void) const
Often used by a "catch" to fetch the user set error string of a thrown socket, but only if EXTENDED e...
virtual bool isPending(Pending pend, timeout_t timeout=TIMEOUT_INF)
Get the status of pending operations.
ssize_t peek(void *buf, size_t len)
Examine contents of next waiting packet.
Simple TCP Stream, to be used with Common C++ Library.
long getSystemError(void) const
The Socket is used as the base for all Internet protocol services under Common C++.
Error setMulticast(bool enable)
void setError(bool enable)
This service is used to turn the error handler on or off for "throwing" exceptions by manipulating th...
ssize_t transmit(const char *buffer, size_t len)
Transmit "send" to use "connected" send rather than sendto.
Error setKeepAlive(bool enable)
UDP sockets implement the TCP SOCK_DGRAM UDP protocol.
int getSegmentSize(void)
Get the buffer size for servers.
IPV4Host getLocal(tpport_t *port=NULL) const
Error join(const IPV4Multicast &ia)
Join a multicast group.
Representing half of a two-way UDP connection, the UDP transmitter can broadcast data to another sele...
bool isRouted(void) const
Return if socket routing is enabled.
__EXPORT AppLog & error(AppLog &sl)
Manipulator for error level.
Error setTimeToLiveByFamily(unsigned char ttl, Family fam=IPV4)
Set the multicast time to live for a multicast socket.
DCCP sockets are used for stream based connected sessions between two sockets.
Error setRouting(bool enable)
SOCKET getTransmitter(void)
unsigned short tpport_t
Transport Protocol Ports.
class __EXPORT SimpleTCPStream
SOCKET volatile so
the actual socket descriptor, in Windows, unlike posix it cannot be used as an file descriptor that w...
IPV4Host getPeer(tpport_t *port=NULL) const
The Mutex class is used to protect a section of code so that at any given time only a single thread c...
Error setTypeOfService(Tos tos)
void endReceiver(void)
End receiver.
IPV4Host getNAT(tpport_t *port) const
This is a generic and portable string class.
Error getErrorNumber(void) const
Often used by a "catch" to fetch the last error of a thrown socket.
bool isBroadcast(void) const
Return if broadcast has been enabled for the specified socket.
IPV4Host getLocal(tpport_t *port=NULL) const
Used to get local bound address.
The TCP session is used to primarily to represent a client connection that can be managed on a sepera...
Error setMulticast(bool enable)
Set the multicast.
ssize_t send(const void *buf, size_t len)
Transmit "send" to use "connected" send rather than sendto.
IPV4Host getPeer(tpport_t *port=NULL) const
Error drop(const IPV4Multicast &ia)
Error setTimeToLive(char ttl)
Set time to live.
The broadcast address object is used to store the broadcast address for a specific subnet...
Error join(const IPV4Multicast &ia)
Error drop(const IPV4Multicast &ia)
Drop membership from a multicast group.
SOCKET getReceiver(void) const
Error setLoopbackByFamily(bool enable, Family family=IPV4)
Set the multicast loopback flag for the socket.
Network addresses and sockets related classes.
bool isOutputReady(unsigned long timeout=0l)
See if output queue is empty for sending more packets.
ssize_t receive(void *buf, size_t len)
Receive a data packet from the connected peer host.
void endSocket(void)
Used as the default destructor for ending a socket.
TCP sockets are used for stream based connected sessions between two sockets.
IPV4Host getIPV4Local(tpport_t *port=NULL) const
Get the local address and port number this socket is currently bound to.
Error setLoopback(bool enable)
Set the loopback.
Error setBroadcast(bool enable)
Representing a UDP socket used for subnet broadcasts, this class provides an alternate binding and se...
void endTransmitter(void)
Stop transmitter.
virtual IPV4Host getIPV4Sender(tpport_t *port=NULL) const
May be used to examine the origin of data waiting in the socket receive queue.
IPV4Host getSender(tpport_t *port=NULL) const
SOCKET getSocket(void)
Fetch out the socket.
void error(const char *err) const
This service is used to throw application defined socket errors where the application specific error ...
bool isInputReady(timeout_t timeout=TIMEOUT_INF)
See if input queue has data packets available.
Error setMulticast(bool enable)
std::iostream * tcp(void)
Used in derived classes to refer to the current object via it's iostream.
size_t getBufferSize(void) const
Return the size of the current stream buffering used.
Error setMulticastByFamily(bool enable, Family family=IPV4)
Setting multicast binds the multicast interface used for the socket to the interface the socket itsel...
ssize_t peek(void *buf, size_t len)
Examine contents of next waiting packet.
Every thread of execution in an application is created by instantiating an object of a class derived ...
void setTimeout(timeout_t timer)
Set the I/O operation timeout for socket I/O operations.
A specialization of IPV4Address that provides address validation for multicast addresses.
bool isPendingConnection(timeout_t timeout=TIMEOUT_INF)
Used to wait for pending connection requests.
UDP duplex connections impliment a bi-directional point-to-point UDP session between two peer hosts...
Error setRouting(bool enable)
Error setTimeToLive(unsigned char ttl)
This object is used to hold the actual and valid internet address of a specific host machine that wil...
bool isPendingReceive(timeout_t timeout)
Check for pending data.
IPV4Host getRequest(tpport_t *port=NULL) const
Return address and port of next connection request.
The network name and address objects are all derived from a common IPV4Address base class...
TCP streams are used to represent TCP client connections to a server by TCP protocol servers for acce...
Error setRouting(bool enable)
Set the socket routing to indicate if outgoing messages should bypass normal routing (set false)...
Error setKeepAlive(bool enable)
Set the keep-alive status of this socket and if keep-alive messages will be sent. ...
Error setBroadcast(bool enable)
Set the subnet broadcast flag for the socket.
unsigned short tpport_t
Transport Protocol Ports.
Error setBroadcast(bool enable)
Error setTypeOfService(Tos service)
Set packet scheduling on platforms which support ip quality of service conventions.
bool isPendingConnection(timeout_t timeout=TIMEOUT_INF)
Used to wait for pending connection requests.
Representing half of a two-way UDP connection, the UDP receiver can receive data from another peer ho...