1 ////////////////////////////////////////////////////////////////////////////////
3 // Author: Andy Rushton
4 // Copyright: (c) Southampton University 1999-2004
5 // (c) Andy Rushton 2004-2009
6 // License: BSD License, see ../docs/license.html
8 // Contains all the platform-specific socket handling used by the TCP and UDP classes
10 // TODO - any conversion required to support IPv6
12 ////////////////////////////////////////////////////////////////////////////////
14 #include "ip_sockets.hpp"
15 #include "dprintf.hpp"
19 // Windoze-specific includes
21 #define ERRNO WSAGetLastError()
22 #define HERRNO WSAGetLastError()
23 #define IOCTL ioctlsocket
24 #define CLOSE closesocket
25 #define SHUT_RDWR SD_BOTH
26 #define EINPROGRESS WSAEINPROGRESS
27 #define EWOULDBLOCK WSAEWOULDBLOCK
28 #define ECONNRESET WSAECONNRESET
31 // Generic Unix includes
32 // fix for older versions of Darwin?
33 #define _BSD_SOCKLEN_T_ int
34 #include <sys/types.h>
35 #include <sys/socket.h>
36 #include <sys/ioctl.h>
38 #include <netinet/in.h>
42 #define INVALID_SOCKET -1
44 #define HERRNO h_errno
46 #define SOCKET_ERROR -1
49 #define SOCKLEN_T socklen_t
51 // Sun put some definitions in a different place
52 #include <sys/filio.h>
56 ////////////////////////////////////////////////////////////////////////////////
61 ////////////////////////////////////////////////////////////////////////////////
64 // get an operating-system error message given an error code
65 static std::string
error_string(int error
)
67 std::string result
= "error " + dformat("%d",error
);
70 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
|FORMAT_MESSAGE_FROM_SYSTEM
|FORMAT_MESSAGE_IGNORE_INSERTS
,
73 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
), // "User default language"
81 // the error message is for some perverse reason newline terminated - remove this
82 if (result
[result
.size()-1] == '\n')
83 result
.erase(result
.end()-1);
84 if (result
[result
.size()-1] == '\r')
85 result
.erase(result
.end()-1);
87 char* message
= strerror(error
);
88 if (message
&& message
[0])
94 // convert address:port into a sockaddr
95 static void convert_address(unsigned long address
, unsigned short port
, sockaddr
& sa
)
97 sa
.sa_family
= AF_INET
;
98 unsigned short network_port
= htons(port
);
99 memcpy(&sa
.sa_data
[0], &network_port
, sizeof(network_port
));
100 unsigned long network_address
= htonl(address
);
101 memcpy(&sa
.sa_data
[2], &network_address
, sizeof(network_address
));
104 // // convert host:port into a sockaddr
105 // static void convert_host(hostent& host, unsigned short port, sockaddr& sa)
107 // sa.sa_family = host.h_addrtype;
108 // unsigned short network_port = htons(port);
109 // memcpy(&sa.sa_data[0], &network_port, sizeof(network_port));
110 // memcpy(&sa.sa_data[2], host.h_addr, host.h_length);
113 // convert sockaddr to address:port
114 static void convert_sockaddr(const sockaddr
& sa
, unsigned long& address
, unsigned short& port
)
116 unsigned short network_port
= 0;
117 memcpy(&network_port
, &sa
.sa_data
[0], sizeof(network_port
));
118 port
= ntohs(network_port
);
119 unsigned long network_address
= 0;
120 memcpy(&network_address
, &sa
.sa_data
[2], sizeof(network_address
));
121 address
= ntohl(network_address
);
124 ////////////////////////////////////////////////////////////////////////////////
126 // Windows requires that Winsock is initialised before use and closed after
127 // These routines initialise once on first use and close on the destruction of the last object using it
128 // on non-windows platforms, I still increment/decrement the sockets count variable for diagnostic purposes
130 static int sockets_count
= 0;
132 static int sockets_init(void)
135 if (sockets_count
++ == 0)
138 WSAData winsock_info
;
139 // request Winsock 2.0 or higher
140 error
= WSAStartup(MAKEWORD(2,0),&winsock_info
);
146 static int sockets_close(void)
149 if (--sockets_count
== 0)
152 if (WSACleanup() == SOCKET_ERROR
)
159 ////////////////////////////////////////////////////////////////////////////////
160 // Socket Implementation - common code to manipulate a TCP socket
162 class IP_socket_internals
165 IP_socket_type m_type
;
167 unsigned long m_remote_address
;
168 unsigned short m_remote_port
;
170 mutable std::string m_message
;
173 // disable copying of the internals
174 IP_socket_internals(const IP_socket_internals
&);
175 IP_socket_internals
& operator=(const IP_socket_internals
&);
179 ////////////////////////////////////////////////////////////////////////////
180 // PIMPL alias counting
193 ////////////////////////////////////////////////////////////////////////////
194 // constructors/destructors
196 // construct an invalid socket
197 IP_socket_internals(void) : m_type(undefined_socket_type
), m_socket(INVALID_SOCKET
), m_error(0), m_count(1)
199 set_error(sockets_init());
203 ~IP_socket_internals(void)
206 set_error(sockets_close());
209 ////////////////////////////////////////////////////////////////////////////
210 // initialisation, connection
212 bool initialised(void) const
214 return m_socket
!= INVALID_SOCKET
;
217 // attach this object to a pre-opened socket
218 bool set(SOCKET socket
, unsigned long remote_address
, unsigned short remote_port
)
220 if (initialised()) close();
223 m_remote_address
= remote_address
;
224 m_remote_port
= remote_port
;
228 // create a raw socket attached to this object
229 bool initialise(IP_socket_type type
)
231 if (initialised()) close();
233 if ((type
!= TCP
) && (type
!= UDP
))
235 set_error(-1, "Illegal socket type");
238 // create an anonymous socket
239 m_socket
= ::socket(AF_INET
, ((type
== TCP
) ? SOCK_STREAM
: SOCK_DGRAM
), 0);
240 if (m_socket
== INVALID_SOCKET
)
246 // record the type on success only
248 // set the socket into non-blocking mode
249 unsigned long nonblocking
= 1;
250 if (IOCTL(m_socket
, FIONBIO
, &nonblocking
) == SOCKET_ERROR
)
258 // function for performing IP lookup (i.e. gethostbyname)
259 // could be standalone but making it a member means that it can use the socket's error handler
260 // - remote_address: IP name or number
261 // - returns the IP address as a number - zero if there's an error
262 unsigned long ip_lookup(const std::string
& remote_address
)
264 unsigned long result
= 0;
265 // Lookup the IP address to convert it into a host record
266 // this DOES lookup IP address names as well (not according to MS help !!)
267 // TODO - convert this to use ::getaddrinfo - ::gethostbyname is deprecated
268 hostent
* host_info
= ::gethostbyname(remote_address
.c_str());
274 // extract the address from the host info
275 unsigned long network_address
= 0;
276 memcpy(&network_address
, host_info
->h_addr
, host_info
->h_length
);
277 result
= ntohl(network_address
);
281 // tests whether a socket is ready for communication
282 bool select(bool readable
, bool writeable
, unsigned wait
)
284 if (!initialised()) return false;
285 // set up the readable set
287 fd_set
* readable_set_ptr
= 0;
290 FD_ZERO(&readable_set
);
291 FD_SET(m_socket
,&readable_set
);
292 readable_set_ptr
= &readable_set
;
294 // set up the writeable set
295 fd_set writeable_set
;
296 fd_set
* writeable_set_ptr
= 0;
299 FD_ZERO(&writeable_set
);
300 FD_SET(m_socket
,&writeable_set
);
301 writeable_set_ptr
= &writeable_set
;
303 // TODO - check the error set and lookup the error?
304 fd_set
* error_set_ptr
= 0;
305 // set up the timout value
306 // Note: a null pointer implements a blocking select
307 // a pointer to a zero value implements a zero-wait poll
308 // a pointer to a positive value implements a poll with a timeout
309 // I currently only implement polling with timeout which may be zero - no blocking
311 timeval
* timeout_ptr
= 0;
312 timeout
.tv_sec
= wait
/1000000;
313 timeout
.tv_usec
= wait%1000000
;
314 timeout_ptr
= &timeout
;
315 // now test the socket
316 int select_result
= ::select(m_socket
+1, readable_set_ptr
, writeable_set_ptr
, error_set_ptr
, timeout_ptr
);
317 switch(select_result
)
320 // select failed with an error - trap the error
324 // timeout exceeded without a connection appearing
327 // at least one connection is pending
328 // TODO - do we need to do the extra socket options checking on Posix?
329 // TODO - does this connect in any way to the error_set above?
334 // bind the socket to a port so that it can receive from specific address
335 bool bind(unsigned long remote_address
, unsigned short local_port
)
337 if (!initialised()) return false;
338 // name the socket and bind it to a port - this is a requirement for a server
340 convert_address(INADDR_ANY
, local_port
, server
);
341 if (::bind(m_socket
, &server
, sizeof(server
)) == SOCKET_ERROR
)
350 // bind the socket to a port so that it can receive from any address
351 bool bind_any(unsigned short local_port
)
353 return bind(INADDR_ANY
, local_port
);
356 // set this socket up to be a listening port
357 // must have been bound to a local port already
358 // - length of backlog queue to manage - may be zero
359 // - returns success status
360 bool listen(unsigned short queue
)
362 if (!initialised()) return false;
363 // set the port to listen for incoming connections
364 if (::listen(m_socket
, (int)queue
) == SOCKET_ERROR
)
373 // test whether there's an incoming connection on the socket
374 // only applicable if it has been set up as a listening port
375 bool accept_ready(unsigned wait
)
377 // the test for a connection being ready is the same as the test for whether the socket is readable
378 // see documentation for select
379 return select(true, false, wait
);
382 // accept a connection on the socket
383 // only applicable if it has been set up as a listening port
384 // - returns socket filled in with the accepted connection's details - or with the error fields set
385 IP_socket
accept(void)
387 if (!initialised()) return IP_socket();
389 // accept the connection, at the same time getting the address of the connecting client
391 SOCKLEN_T saddress_length
= sizeof(saddress
);
392 SOCKET socket
= ::accept(m_socket
, &saddress
, &saddress_length
);
393 if (socket
== INVALID_SOCKET
)
395 // only set the result socket with an error
396 result
.m_impl
->set_error(ERRNO
);
399 // extract the contents of the address
400 unsigned long remote_address
= 0;
401 unsigned short remote_port
= 0;
402 convert_sockaddr(saddress
, remote_address
, remote_port
);
403 result
.m_impl
->set(socket
, remote_address
, remote_port
);
407 // client connect to a server
408 // - remote_address: IP number of remote address to connect to
409 // - remote_port: port to connect to
410 bool connect(unsigned long remote_address
, unsigned short remote_port
)
412 if (!initialised()) return false;
413 // fill in the connection data structure
414 sockaddr connect_data
;
415 convert_address(remote_address
, remote_port
, connect_data
);
416 // connect binds the socket to a local address
417 // if connectionless it simply sets the default remote address
418 // if connectioned it makes the connection
419 if (::connect(m_socket
, &connect_data
, sizeof(connect_data
)) == SOCKET_ERROR
)
421 // the socket is non-blocking, so connect will almost certainly fail with EINPROGRESS which is not an error
422 // only catch real errors
424 if (error
!= EINPROGRESS
&& error
!= EWOULDBLOCK
)
430 // extract the remote connection details for local storage
431 convert_sockaddr(connect_data
, m_remote_address
, m_remote_port
);
435 // test whether a socket is connected and ready to communicate
436 bool connected(unsigned wait
)
438 if (!initialised()) return false;
439 // Linux and Windows docs say test with select for whether socket is
440 // writable. However, a problem has been reported with Linux whereby
441 // the OS will report a socket as writable when it isn't
442 // first use the select method
443 if (!select(false, true, wait
))
446 // Windows needs no further processing - select method works
449 // Posix version needs further checking using the socket options
450 // DJDM: socket has returned EINPROGRESS on the first attempt at connection
451 // it has also returned that it can be written to
452 // we must now ask it if it has actually connected - using getsockopt
454 socklen_t serror
= sizeof(int);
455 if (::getsockopt(m_socket
, SOL_SOCKET
, SO_ERROR
, &error
, &serror
)==0)
456 // handle the error value - one of them means that the socket has connected
457 if (!error
|| error
== EISCONN
)
468 if (shutdown(m_socket
,SHUT_RDWR
) == SOCKET_ERROR
)
473 if (CLOSE(m_socket
) == SOCKET_ERROR
)
479 m_socket
= INVALID_SOCKET
;
480 m_remote_address
= 0;
485 ////////////////////////////////////////////////////////////////////////////
488 bool send_ready(unsigned wait
)
490 // determines whether the socket is ready to send by testing whether it is writable
491 return select(false, true, wait
);
494 bool send (std::string
& data
)
496 if (!initialised()) return false;
497 // send the data - this will never block but may not send all the data
498 int bytes
= ::send(m_socket
, data
.c_str(), data
.size(), 0);
499 if (bytes
== SOCKET_ERROR
)
504 // remove the sent bytes from the data buffer so that the buffer represents the data still to be sent
509 bool send_packet(std::string
& data
, unsigned long address
= 0, unsigned short port
= 0)
511 if (!initialised()) return false;
512 // if no address specified, rely on the socket having been connected (can I test this?)
513 // so use the standard send, otherwise use the sendto function
517 bytes
= ::send(m_socket
, data
.c_str(), data
.size(), 0);
522 convert_address(address
, port
, saddress
);
523 bytes
= ::sendto(m_socket
, data
.c_str(), data
.size(), 0, &saddress
, sizeof(saddress
));
525 if (bytes
== SOCKET_ERROR
)
530 // remove the sent bytes from the data buffer so that the buffer represents the data still to be sent
535 bool receive_ready(unsigned wait
)
537 // determines whether the socket is ready to receive by testing whether it is readable
538 return select(true, false, wait
);
541 bool receive (std::string
& data
)
543 if (!initialised()) return false;
544 // determine how much data is available to read
545 unsigned long bytes
= 0;
546 if (IOCTL(m_socket
, FIONREAD
, &bytes
) == SOCKET_ERROR
)
551 // get the data up to the amount claimed to be present - this is non-blocking
552 char* buffer
= new char[bytes
+1];
553 int read
= ::recv(m_socket
, buffer
, bytes
, 0);
554 if (read
== SOCKET_ERROR
)
563 // TODO - check whether this is an appropriate conditon to close the socket
568 // this is binary data so copy the bytes including nulls
569 data
.append(buffer
,read
);
575 bool receive_packet(std::string
& data
, unsigned long& address
, unsigned short& port
)
577 if (!initialised()) return false;
578 // determine how much data is available to read
579 unsigned long bytes
= 0;
580 if (IOCTL(m_socket
, FIONREAD
, &bytes
) == SOCKET_ERROR
)
585 // get the data up to the amount claimed to be present - this is non-blocking
586 // also get the sender's details
587 char* buffer
= new char[bytes
+1];
589 SOCKLEN_T saddress_length
= sizeof(saddress
);
590 int read
= ::recvfrom(m_socket
, buffer
, bytes
, 0, &saddress
, &saddress_length
);
591 if (read
== SOCKET_ERROR
)
593 // UDP connection reset means that a previous sent failed to deliver cos the address was unknown
594 // this is NOT an error with the sending server socket, which IS still usable
596 if (error
!= ECONNRESET
)
604 // this is binary data so copy the bytes including nulls
605 data
.append(buffer
,read
);
606 // also retrieve the sender's details
607 convert_sockaddr(saddress
, address
, port
);
612 bool receive_packet(std::string
& data
)
614 // call the above and then discard the address details
615 unsigned long address
= 0;
616 unsigned short port
= 0;
617 return receive_packet(data
, address
, port
);
620 ////////////////////////////////////////////////////////////////////////////
623 IP_socket_type
type(void) const
628 unsigned short local_port(void) const
630 if (!initialised()) return 0;
632 SOCKLEN_T saddress_length
= sizeof(saddress
);
633 if (::getsockname(m_socket
, &saddress
, &saddress_length
) != 0)
638 unsigned long address
= 0;
639 unsigned short port
= 0;
640 convert_sockaddr(saddress
, address
, port
);
644 unsigned long remote_address(void) const
646 return m_remote_address
;
649 unsigned short remote_port(void) const
651 return m_remote_port
;
654 ////////////////////////////////////////////////////////////////////////////
657 void set_error (int error
, const char* message
= 0) const
662 if (message
&& (message
[0] != 0))
665 m_message
= error_string(error
);
669 int error(void) const
674 void clear_error (void) const
680 std::string
message(void) const
687 ////////////////////////////////////////////////////////////////////////////////
688 // Socket - common code to manipulate a socket
690 // create an uninitialised socket
691 IP_socket::IP_socket(void) : m_impl(new IP_socket_internals
)
695 // create an initialised socket
696 // - type: create either a TCP or UDP socket - if neither, creates an uninitialised socket
697 IP_socket::IP_socket(IP_socket_type type
) : m_impl(new IP_socket_internals
)
702 // destroy the socket, closing it if open
703 IP_socket::~IP_socket(void)
705 if (m_impl
->decrement())
709 ////////////////////////////////////////////////////////////////////////////
710 // copying is implemented as aliasing
712 IP_socket::IP_socket(const IP_socket
& right
) : m_impl(0)
714 // make this an alias of right
715 m_impl
= right
.m_impl
;
719 IP_socket
& IP_socket::operator=(const IP_socket
& right
)
721 // make self-copy safe
722 if (m_impl
== right
.m_impl
) return *this;
723 // first dealias the existing implementation
724 if (m_impl
->decrement())
726 // now make this an alias of right
727 m_impl
= right
.m_impl
;
732 ////////////////////////////////////////////////////////////////////////////
733 // initialisation, connection
735 // initialise the socket
736 // - type: create either a TCP or UDP socket
737 // - returns success status
738 bool IP_socket::initialise(IP_socket_type type
)
740 return m_impl
->initialise(type
);
743 // test whether this is an initialised socket
744 // - returns whether this is initialised
745 bool IP_socket::initialised(void) const
747 return m_impl
->initialised();
750 // close, i.e. disconnect the socket
751 // - returns a success flag
752 bool IP_socket::close(void)
754 return m_impl
->close();
757 // function for performing IP lookup (i.e. gethostbyname)
758 // could be standalone but making it a member means that it can use the socket's error handler
759 // - remote_address: IP name (stlplus.sourceforge.net) or dotted number (216.34.181.96)
760 // - returns the IP address as a long integer - zero if there's an error
761 unsigned long IP_socket::ip_lookup(const std::string
& remote_address
)
763 return m_impl
->ip_lookup(remote_address
);
766 // test whether a socket is ready to communicate
767 // - readable: test whether socket is ready to read
768 // - writeable: test whether a socket is ready to write
769 // - timeout: if socket is not ready, time to wait before giving up - in micro-seconds - 0 means don't wait
770 // returns false if not ready or error - use error() method to tell - true if ready
771 bool IP_socket::select(bool readable
, bool writeable
, unsigned timeout
)
773 return m_impl
->select(readable
, writeable
, timeout
);
776 // bind the socket to a port so that it can receive from specific address - typically used by a client
777 // - remote_address: IP number of remote server to send/receive to/from
778 // - local_port: port on local machine to bind to the address
779 // - returns success flag
780 bool IP_socket::bind(unsigned long remote_address
, unsigned short local_port
)
782 return m_impl
->bind(remote_address
, local_port
);
785 // bind the socket to a port so that it can receive from any address - typically used by a server
786 // - local_port: port on local machine to bind to the address
787 // - returns success flag
788 bool IP_socket::bind_any(unsigned short local_port
)
790 return m_impl
->bind_any(local_port
);
793 // initialise a socket and set this socket up to be a listening port
794 // - queue: length of backlog queue to manage - may be zero
795 // - returns success status
796 bool IP_socket::listen(unsigned short queue
)
798 return m_impl
->listen(queue
);
801 // test for a connection on the object's socket - only applicable if it has been set up as a listening port
802 // - returns true if a connection is ready to be accepted
803 bool IP_socket::accept_ready(unsigned timeout
) const
805 return m_impl
->accept_ready(timeout
);
808 // accept a connection on the object's socket - only applicable if it has been set up as a listening port
809 // - returns the connection as a new socket
810 IP_socket
IP_socket::accept(void)
812 return m_impl
->accept();
815 // client connect to a server
816 // - address: IP number already lookup up with ip_lookup
817 // - port: port to connect to
818 // - returns a success flag
819 bool IP_socket::connect(unsigned long address
, unsigned short port
)
821 return m_impl
->connect(address
, port
);
824 // test whether a socket is connected and ready to communicate, returns on successful connect or timeout
825 // - timeout: how long to wait in microseconds if not connected yet
826 // - returns success flag
827 bool IP_socket::connected(unsigned timeout
)
829 return m_impl
->connected(timeout
);
832 ////////////////////////////////////////////////////////////////////////////
835 // test whether a socket is connected and ready to send data, returns if ready or on timeout
836 // - timeout: how long to wait in microseconds if not connected yet (blocking)
838 bool IP_socket::send_ready(unsigned timeout
)
840 return m_impl
->send_ready(timeout
);
843 // send data through the socket - if the data is long only part of it may
844 // be sent. The sent part is removed from the data, so the same string can
845 // be sent again and again until it is empty.
846 // - data: string containing data to be sent - any data successfully sent is removed
847 // - returns success flag
848 bool IP_socket::send (std::string
& data
)
850 return m_impl
->send(data
);
853 // send data through a connectionless (UDP) socket
854 // the data will be sent as a single packet
855 // - packet: string containing data to be sent - any data successfully sent is removed
856 // - remote_address: address of the remote host to send to - optional if the socket has been connected to remote
857 // - remote_port: port of the remote host to send to - optional if the socket has been connected to remote
858 // - returns success flag
859 bool IP_socket::send_packet(std::string
& packet
, unsigned long remote_address
, unsigned short remote_port
)
861 return m_impl
->send_packet(packet
, remote_address
, remote_port
);
864 // send data through a connectionless (UDP) socket
865 // the data will be sent as a single packet
866 // only works if the socket has been connected to remote
867 // - packet: string containing data to be sent - any data successfully sent is removed
868 // - returns success flag
869 bool IP_socket::send_packet(std::string
& packet
)
871 return m_impl
->send_packet(packet
);
874 // test whether a socket is connected and ready to receive data, returns if ready or on timeout
875 // - timeout: how long to wait in microseconds if not connected yet (blocking)
877 bool IP_socket::receive_ready(unsigned timeout
)
879 return m_impl
->receive_ready(timeout
);
882 // receive data through a connection-based (TCP) socket
883 // if the data is long only part of it may be received. The received data
884 // is appended to the string, building it up in stages, so the same string
885 // can be received again and again until all information has been
887 // - data: string receiving data from socket - any data successfully received is appended
888 // - returns success flag
889 bool IP_socket::receive (std::string
& data
)
891 return m_impl
->receive(data
);
894 // receive data through a connectionless (UDP) socket
895 // - packet: string receiving data from socket - any data successfully received is appended
896 // - remote_address: returns the address of the remote host received from
897 // - remote_port: returns the port of the remote host received from
898 // - returns success flag
899 bool IP_socket::receive_packet(std::string
& packet
, unsigned long& remote_address
, unsigned short& remote_port
)
901 return m_impl
->receive_packet(packet
, remote_address
, remote_port
);
904 // variant of above which does not give back the address and port of the sender
905 // receive data through a connectionless (UDP) socket
906 // - packet: string receiving data from socket - any data successfully received is appended
907 // - returns success flag
908 bool IP_socket::receive_packet(std::string
& packet
)
910 return m_impl
->receive_packet(packet
);
913 ////////////////////////////////////////////////////////////////////////////
916 IP_socket_type
IP_socket::type(void) const
918 return m_impl
->type();
921 unsigned short IP_socket::local_port(void) const
923 return m_impl
->local_port();
926 unsigned long IP_socket::remote_address(void) const
928 return m_impl
->remote_address();
931 unsigned short IP_socket::remote_port(void) const
933 return m_impl
->remote_port();
936 ////////////////////////////////////////////////////////////////////////////
939 void IP_socket::set_error (int error
, const std::string
& message
) const
941 m_impl
->set_error(error
, message
.c_str());
944 void IP_socket::clear_error (void) const
946 m_impl
->clear_error();
949 int IP_socket::error(void) const
951 return m_impl
->error();
954 std::string
IP_socket::message(void) const
956 return m_impl
->message();
959 ////////////////////////////////////////////////////////////////////////////////
961 } // end namespace stlplus