1 /** \file Socket.cpp
2  **	\date  2004-02-13
3  **	\author grymse@alhem.net
4 **/
5 /*
6 Copyright (C) 2004-2011  Anders Hedstrom
7 
8 This library is made available under the terms of the GNU GPL, with
9 the additional exemption that compiling, linking, and/or using OpenSSL
10 is allowed.
11 
12 If you would like to use this library in a closed-source application,
13 a separate license agreement is available. For information about
14 the closed-source license agreement for the C++ sockets library,
15 please visit http://www.alhem.net/Sockets/license.html and/or
16 email license@alhem.net.
17 
18 This program is free software; you can redistribute it and/or
19 modify it under the terms of the GNU General Public License
20 as published by the Free Software Foundation; either version 2
21 of the License, or (at your option) any later version.
22 
23 This program is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26 GNU General Public License for more details.
27 
28 You should have received a copy of the GNU General Public License
29 along with this program; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
31 */
32 #include "Socket.h"
33 #ifdef _WIN32
34 #ifdef _MSC_VER
35 #pragma warning(disable:4786)
36 #endif
37 #include <stdlib.h>
38 #else
39 #include <errno.h>
40 #include <netdb.h>
41 #endif
42 #include <ctype.h>
43 #include <fcntl.h>
44 
45 #include "Utility.h"
46 
47 #include "SocketAddress.h"
48 #include "SocketHandler.h"
49 #ifdef ENABLE_EXCEPTIONS
50 #include "Exception.h"
51 #endif
52 #include "Ipv4Address.h"
53 #ifdef ENABLE_IPV6
54 #include "Ipv6Address.h"
55 #endif
56 #include "SocketThread.h"
57 
58 #ifdef _DEBUG
59 #define DEB(x) x; fflush(stderr);
60 #else
61 #define DEB(x)
62 #endif
63 
64 #ifdef SOCKETS_NAMESPACE
65 namespace SOCKETS_NAMESPACE {
66 #endif
67 
68 
69 // statics
70 #ifdef _WIN32
71 WSAInitializer Socket::m_winsock_init;
72 #endif
73 socketuid_t Socket::m_next_uid = 0;
74 
75 
Socket(ISocketHandler & h)76 Socket::Socket(ISocketHandler& h)
77 //:m_flags(0)
78 :m_handler(h)
79 ,m_socket( INVALID_SOCKET )
80 ,m_bDel(false)
81 ,m_bClose(false)
82 ,m_tCreate(time(NULL))
83 ,m_parent(NULL)
84 ,m_b_disable_read(false)
85 ,m_connected(false)
86 ,m_b_erased_by_handler(false)
87 ,m_tClose(0)
88 ,m_client_remote_address(NULL)
89 ,m_remote_address(NULL)
90 ,m_traffic_monitor(NULL)
91 ,m_timeout_start(0)
92 ,m_timeout_limit(0)
93 ,m_bLost(false)
94 ,m_uid(++Socket::m_next_uid)
95 ,m_call_on_connect(false)
96 ,m_b_retry_connect(false)
97 #ifdef HAVE_OPENSSL
98 ,m_b_enable_ssl(false)
99 ,m_b_ssl(false)
100 ,m_b_ssl_server(false)
101 #endif
102 #ifdef ENABLE_IPV6
103 ,m_ipv6(false)
104 #endif
105 #ifdef ENABLE_POOL
106 ,m_socket_type(0)
107 ,m_bClient(false)
108 ,m_bRetain(false)
109 #endif
110 #ifdef ENABLE_SOCKS4
111 ,m_bSocks4(false)
112 ,m_socks4_host(h.GetSocks4Host())
113 ,m_socks4_port(h.GetSocks4Port())
114 ,m_socks4_userid(h.GetSocks4Userid())
115 #endif
116 #ifdef ENABLE_DETACH
117 ,m_detach(false)
118 ,m_detached(false)
119 ,m_pThread(NULL)
120 ,m_slave_handler(NULL)
121 #endif
122 {
123 }
124 
125 
~Socket()126 Socket::~Socket()
127 {
128 	Handler().Remove(this);
129 	if (m_socket != INVALID_SOCKET
130 #ifdef ENABLE_POOL
131 		 && !m_bRetain
132 #endif
133 		)
134 	{
135 		Close();
136 	}
137 }
138 
139 
Init()140 void Socket::Init()
141 {
142 }
143 
144 
OnRead()145 void Socket::OnRead()
146 {
147 }
148 
149 
OnWrite()150 void Socket::OnWrite()
151 {
152 }
153 
154 
OnException()155 void Socket::OnException()
156 {
157 	// %! exception doesn't always mean something bad happened, this code should be reworked
158 	// errno valid here?
159 	int err = SoError();
160 	Handler().LogError(this, "exception on select", err, StrError(err), LOG_LEVEL_FATAL);
161 	SetCloseAndDelete();
162 }
163 
164 
OnDelete()165 void Socket::OnDelete()
166 {
167 }
168 
169 
OnConnect()170 void Socket::OnConnect()
171 {
172 }
173 
174 
OnAccept()175 void Socket::OnAccept()
176 {
177 }
178 
179 
Close()180 int Socket::Close()
181 {
182 	if (m_socket == INVALID_SOCKET) // this could happen
183 	{
184 		Handler().LogError(this, "Socket::Close", 0, "file descriptor invalid", LOG_LEVEL_WARNING);
185 		return 0;
186 	}
187 	int n;
188 	Handler().ISocketHandler_Del(this); // remove from fd_set's
189 	if ((n = closesocket(m_socket)) == -1)
190 	{
191 		// failed...
192 		Handler().LogError(this, "close", Errno, StrError(Errno), LOG_LEVEL_ERROR);
193 	}
194 	m_socket = INVALID_SOCKET;
195 	return n;
196 }
197 
198 
CreateSocket(int af,int type,const std::string & protocol)199 SOCKET Socket::CreateSocket(int af,int type, const std::string& protocol)
200 {
201 	struct protoent *p = NULL;
202 	SOCKET s;
203 
204 #ifdef ENABLE_POOL
205 	m_socket_type = type;
206 	m_socket_protocol = protocol;
207 #endif
208 	if (protocol.size())
209 	{
210 		p = getprotobyname( protocol.c_str() );
211 		if (!p)
212 		{
213 			Handler().LogError(this, "getprotobyname", Errno, StrError(Errno), LOG_LEVEL_FATAL);
214 			SetCloseAndDelete();
215 #ifdef ENABLE_EXCEPTIONS
216 			throw Exception(std::string("getprotobyname() failed: ") + StrError(Errno));
217 #endif
218 			return INVALID_SOCKET;
219 		}
220 	}
221 	int protno = p ? p -> p_proto : 0;
222 
223 	s = socket(af, type, protno);
224 	if (s == INVALID_SOCKET)
225 	{
226 		Handler().LogError(this, "socket", Errno, StrError(Errno), LOG_LEVEL_FATAL);
227 		SetCloseAndDelete();
228 #ifdef ENABLE_EXCEPTIONS
229 		throw Exception(std::string("socket() failed: ") + StrError(Errno));
230 #endif
231 		return INVALID_SOCKET;
232 	}
233 	Attach(s);
234 	OnOptions(af, type, protno, s);
235 	Attach(INVALID_SOCKET);
236 	return s;
237 }
238 
239 
Attach(SOCKET s)240 void Socket::Attach(SOCKET s)
241 {
242 	m_socket = s;
243 }
244 
245 
GetSocket()246 SOCKET Socket::GetSocket()
247 {
248 	return m_socket;
249 }
250 
251 
SetDeleteByHandler(bool x)252 void Socket::SetDeleteByHandler(bool x)
253 {
254 	m_bDel = x;
255 }
256 
257 
DeleteByHandler()258 bool Socket::DeleteByHandler()
259 {
260 	return m_bDel;
261 }
262 
263 
SetCloseAndDelete(bool x)264 void Socket::SetCloseAndDelete(bool x)
265 {
266 	if (x != m_bClose)
267 	{
268 		m_bClose = x;
269 		if (x)
270 		{
271 			m_tClose = time(NULL);
272 			Handler().SetClose();
273 		}
274 	}
275 }
276 
277 
CloseAndDelete()278 bool Socket::CloseAndDelete()
279 {
280 	return m_bClose;
281 }
282 
283 
SetRemoteAddress(SocketAddress & ad)284 void Socket::SetRemoteAddress(SocketAddress& ad) //struct sockaddr* sa, socklen_t l)
285 {
286 	m_remote_address = ad.GetCopy();
287 }
288 
289 
GetRemoteSocketAddress()290 std::auto_ptr<SocketAddress> Socket::GetRemoteSocketAddress()
291 {
292 	return m_remote_address -> GetCopy();
293 }
294 
295 
Handler() const296 ISocketHandler& Socket::Handler() const
297 {
298 #ifdef ENABLE_DETACH
299 	if (IsDetached())
300 		return *m_slave_handler;
301 #endif
302 	return m_handler;
303 }
304 
305 
MasterHandler() const306 ISocketHandler& Socket::MasterHandler() const
307 {
308 	return m_handler;
309 }
310 
311 
GetRemoteIP4()312 ipaddr_t Socket::GetRemoteIP4()
313 {
314 	ipaddr_t l = 0;
315 #ifdef ENABLE_IPV6
316 	if (m_ipv6)
317 	{
318 		Handler().LogError(this, "GetRemoteIP4", 0, "get ipv4 address for ipv6 socket", LOG_LEVEL_WARNING);
319 	}
320 #endif
321 	if (m_remote_address.get() != NULL)
322 	{
323 		struct sockaddr *p = *m_remote_address;
324 		struct sockaddr_in *sa = (struct sockaddr_in *)p;
325 		memcpy(&l, &sa -> sin_addr, sizeof(struct in_addr));
326 	}
327 	return l;
328 }
329 
330 
331 #ifdef ENABLE_IPV6
332 #ifdef IPPROTO_IPV6
GetRemoteIP6()333 struct in6_addr Socket::GetRemoteIP6()
334 {
335 	if (!m_ipv6)
336 	{
337 		Handler().LogError(this, "GetRemoteIP6", 0, "get ipv6 address for ipv4 socket", LOG_LEVEL_WARNING);
338 	}
339 	struct sockaddr_in6 fail;
340 	if (m_remote_address.get() != NULL)
341 	{
342 		struct sockaddr *p = *m_remote_address;
343 		memcpy(&fail, p, sizeof(struct sockaddr_in6));
344 	}
345 	else
346 	{
347 		memset(&fail, 0, sizeof(struct sockaddr_in6));
348 	}
349 	return fail.sin6_addr;
350 }
351 #endif
352 #endif
353 
354 
GetRemotePort()355 port_t Socket::GetRemotePort()
356 {
357 	if (!m_remote_address.get())
358 	{
359 		return 0;
360 	}
361 	return m_remote_address -> GetPort();
362 }
363 
364 
GetRemoteAddress()365 std::string Socket::GetRemoteAddress()
366 {
367 	if (!m_remote_address.get())
368 	{
369 		return "";
370 	}
371 	return m_remote_address -> Convert(false);
372 }
373 
374 
GetRemoteHostname()375 std::string Socket::GetRemoteHostname()
376 {
377 	if (!m_remote_address.get())
378 	{
379 		return "";
380 	}
381 	return m_remote_address -> Reverse();
382 }
383 
384 
SetNonblocking(bool bNb)385 bool Socket::SetNonblocking(bool bNb)
386 {
387 #ifdef _WIN32
388 	unsigned long l = bNb ? 1 : 0;
389 	int n = ioctlsocket(m_socket, FIONBIO, &l);
390 	if (n != 0)
391 	{
392 		Handler().LogError(this, "ioctlsocket(FIONBIO)", Errno, "");
393 		return false;
394 	}
395 	return true;
396 #else
397 	if (bNb)
398 	{
399 		if (fcntl(m_socket, F_SETFL, O_NONBLOCK) == -1)
400 		{
401 			Handler().LogError(this, "fcntl(F_SETFL, O_NONBLOCK)", Errno, StrError(Errno), LOG_LEVEL_ERROR);
402 			return false;
403 		}
404 	}
405 	else
406 	{
407 		if (fcntl(m_socket, F_SETFL, 0) == -1)
408 		{
409 			Handler().LogError(this, "fcntl(F_SETFL, 0)", Errno, StrError(Errno), LOG_LEVEL_ERROR);
410 			return false;
411 		}
412 	}
413 	return true;
414 #endif
415 }
416 
417 
SetNonblocking(bool bNb,SOCKET s)418 bool Socket::SetNonblocking(bool bNb, SOCKET s)
419 {
420 #ifdef _WIN32
421 	unsigned long l = bNb ? 1 : 0;
422 	int n = ioctlsocket(s, FIONBIO, &l);
423 	if (n != 0)
424 	{
425 		Handler().LogError(this, "ioctlsocket(FIONBIO)", Errno, "");
426 		return false;
427 	}
428 	return true;
429 #else
430 	if (bNb)
431 	{
432 		if (fcntl(s, F_SETFL, O_NONBLOCK) == -1)
433 		{
434 			Handler().LogError(this, "fcntl(F_SETFL, O_NONBLOCK)", Errno, StrError(Errno), LOG_LEVEL_ERROR);
435 			return false;
436 		}
437 	}
438 	else
439 	{
440 		if (fcntl(s, F_SETFL, 0) == -1)
441 		{
442 			Handler().LogError(this, "fcntl(F_SETFL, 0)", Errno, StrError(Errno), LOG_LEVEL_ERROR);
443 			return false;
444 		}
445 	}
446 	return true;
447 #endif
448 }
449 
450 
Ready()451 bool Socket::Ready()
452 {
453 	if (m_socket != INVALID_SOCKET && !CloseAndDelete())
454 		return true;
455 	return false;
456 }
457 
458 
OnLine(const std::string &)459 void Socket::OnLine(const std::string& )
460 {
461 }
462 
463 
OnConnectFailed()464 void Socket::OnConnectFailed()
465 {
466 }
467 
468 
GetParent()469 Socket *Socket::GetParent()
470 {
471 	return m_parent;
472 }
473 
474 
SetParent(Socket * x)475 void Socket::SetParent(Socket *x)
476 {
477 	m_parent = x;
478 }
479 
480 
GetPort()481 port_t Socket::GetPort()
482 {
483 	Handler().LogError(this, "GetPort", 0, "GetPort only implemented for ListenSocket", LOG_LEVEL_WARNING);
484 	return 0;
485 }
486 
487 
OnConnectRetry()488 bool Socket::OnConnectRetry()
489 {
490 	return true;
491 }
492 
493 
494 #ifdef ENABLE_RECONNECT
OnReconnect()495 void Socket::OnReconnect()
496 {
497 }
498 #endif
499 
500 
Uptime()501 time_t Socket::Uptime()
502 {
503 	return time(NULL) - m_tCreate;
504 }
505 
506 
507 #ifdef ENABLE_IPV6
SetIpv6(bool x)508 void Socket::SetIpv6(bool x)
509 {
510 	m_ipv6 = x;
511 }
512 
513 
IsIpv6()514 bool Socket::IsIpv6()
515 {
516 	return m_ipv6;
517 }
518 #endif
519 
520 
DisableRead(bool x)521 void Socket::DisableRead(bool x)
522 {
523 	m_b_disable_read = x;
524 }
525 
526 
IsDisableRead()527 bool Socket::IsDisableRead()
528 {
529 	return m_b_disable_read;
530 }
531 
532 
SendBuf(const char *,size_t,int)533 void Socket::SendBuf(const char *,size_t,int)
534 {
535 }
536 
537 
Send(const std::string &,int)538 void Socket::Send(const std::string&,int)
539 {
540 }
541 
542 
SetConnected(bool x)543 void Socket::SetConnected(bool x)
544 {
545 	m_connected = x;
546 }
547 
548 
IsConnected()549 bool Socket::IsConnected()
550 {
551 	return m_connected;
552 }
553 
554 
OnDisconnect()555 void Socket::OnDisconnect()
556 {
557 }
558 
559 
OnDisconnect(short,int)560 void Socket::OnDisconnect(short, int)
561 {
562 }
563 
564 
SetLost()565 void Socket::SetLost()
566 {
567 	m_bLost = true;
568 }
569 
570 
Lost()571 bool Socket::Lost()
572 {
573 	return m_bLost;
574 }
575 
576 
SetErasedByHandler(bool x)577 void Socket::SetErasedByHandler(bool x)
578 {
579 	m_b_erased_by_handler = x;
580 }
581 
582 
ErasedByHandler()583 bool Socket::ErasedByHandler()
584 {
585 	return m_b_erased_by_handler;
586 }
587 
588 
TimeSinceClose()589 time_t Socket::TimeSinceClose()
590 {
591 	return time(NULL) - m_tClose;
592 }
593 
594 
SetClientRemoteAddress(SocketAddress & ad)595 void Socket::SetClientRemoteAddress(SocketAddress& ad)
596 {
597 	if (!ad.IsValid())
598 	{
599 		Handler().LogError(this, "SetClientRemoteAddress", 0, "remote address not valid", LOG_LEVEL_ERROR);
600 	}
601 	m_client_remote_address = ad.GetCopy();
602 }
603 
604 
GetClientRemoteAddress()605 std::auto_ptr<SocketAddress> Socket::GetClientRemoteAddress()
606 {
607 	if (!m_client_remote_address.get())
608 	{
609 		Handler().LogError(this, "GetClientRemoteAddress", 0, "remote address not yet set", LOG_LEVEL_ERROR);
610 	}
611 	return m_client_remote_address -> GetCopy();
612 }
613 
614 
GetBytesSent(bool)615 uint64_t Socket::GetBytesSent(bool)
616 {
617 	return 0;
618 }
619 
620 
GetBytesReceived(bool)621 uint64_t Socket::GetBytesReceived(bool)
622 {
623 	return 0;
624 }
625 
626 
SetCallOnConnect(bool x)627 void Socket::SetCallOnConnect(bool x)
628 {
629 	m_call_on_connect = x;
630 	if (x)
631 		Handler().SetCallOnConnect();
632 }
633 
634 
CallOnConnect()635 bool Socket::CallOnConnect()
636 {
637 	return m_call_on_connect;
638 }
639 
640 
SetRetryClientConnect(bool x)641 void Socket::SetRetryClientConnect(bool x)
642 {
643 	m_b_retry_connect = x;
644 	if (x)
645 		Handler().SetRetry();
646 }
647 
648 
RetryClientConnect()649 bool Socket::RetryClientConnect()
650 {
651 	return m_b_retry_connect;
652 }
653 
654 
655 #ifdef HAVE_OPENSSL
OnSSLConnect()656 void Socket::OnSSLConnect()
657 {
658 }
659 
660 
OnSSLAccept()661 void Socket::OnSSLAccept()
662 {
663 }
664 
665 
SSLNegotiate()666 bool Socket::SSLNegotiate()
667 {
668 	return false;
669 }
670 
671 
IsSSL()672 bool Socket::IsSSL()
673 {
674 	return m_b_enable_ssl;
675 }
676 
677 
EnableSSL(bool x)678 void Socket::EnableSSL(bool x)
679 {
680 	m_b_enable_ssl = x;
681 }
682 
683 
IsSSLNegotiate()684 bool Socket::IsSSLNegotiate()
685 {
686 	return m_b_ssl;
687 }
688 
689 
SetSSLNegotiate(bool x)690 void Socket::SetSSLNegotiate(bool x)
691 {
692 	m_b_ssl = x;
693 }
694 
695 
IsSSLServer()696 bool Socket::IsSSLServer()
697 {
698 	return m_b_ssl_server;
699 }
700 
701 
SetSSLServer(bool x)702 void Socket::SetSSLServer(bool x)
703 {
704 	m_b_ssl_server = x;
705 }
706 
707 
OnSSLConnectFailed()708 void Socket::OnSSLConnectFailed()
709 {
710 }
711 
712 
OnSSLAcceptFailed()713 void Socket::OnSSLAcceptFailed()
714 {
715 }
716 #endif // HAVE_OPENSSL
717 
718 
719 #ifdef ENABLE_POOL
CopyConnection(Socket * sock)720 void Socket::CopyConnection(Socket *sock)
721 {
722 	Attach( sock -> GetSocket() );
723 #ifdef ENABLE_IPV6
724 	SetIpv6( sock -> IsIpv6() );
725 #endif
726 	SetSocketType( sock -> GetSocketType() );
727 	SetSocketProtocol( sock -> GetSocketProtocol() );
728 
729 	SetClientRemoteAddress( *sock -> GetClientRemoteAddress() );
730 	SetRemoteAddress( *sock -> GetRemoteSocketAddress() );
731 }
732 
733 
SetIsClient()734 void Socket::SetIsClient()
735 {
736 	m_bClient = true;
737 }
738 
739 
SetSocketType(int x)740 void Socket::SetSocketType(int x)
741 {
742 	m_socket_type = x;
743 }
744 
745 
GetSocketType()746 int Socket::GetSocketType()
747 {
748 	return m_socket_type;
749 }
750 
751 
SetSocketProtocol(const std::string & x)752 void Socket::SetSocketProtocol(const std::string& x)
753 {
754 	m_socket_protocol = x;
755 }
756 
757 
GetSocketProtocol()758 const std::string& Socket::GetSocketProtocol()
759 {
760 	return m_socket_protocol;
761 }
762 
763 
SetRetain()764 void Socket::SetRetain()
765 {
766 	if (m_bClient)
767 		m_bRetain = true;
768 }
769 
770 
Retain()771 bool Socket::Retain()
772 {
773 	return m_bRetain;
774 }
775 
776 
777 #endif // ENABLE_POOL
778 
779 
780 #ifdef ENABLE_SOCKS4
OnSocks4Connect()781 void Socket::OnSocks4Connect()
782 {
783 	Handler().LogError(this, "OnSocks4Connect", 0, "Use with TcpSocket only");
784 }
785 
786 
OnSocks4ConnectFailed()787 void Socket::OnSocks4ConnectFailed()
788 {
789 	Handler().LogError(this, "OnSocks4ConnectFailed", 0, "Use with TcpSocket only");
790 }
791 
792 
OnSocks4Read()793 bool Socket::OnSocks4Read()
794 {
795 	Handler().LogError(this, "OnSocks4Read", 0, "Use with TcpSocket only");
796 	return true;
797 }
798 
799 
SetSocks4Host(const std::string & host)800 void Socket::SetSocks4Host(const std::string& host)
801 {
802 	Utility::u2ip(host, m_socks4_host);
803 }
804 
805 
Socks4()806 bool Socket::Socks4()
807 {
808 	return m_bSocks4;
809 }
810 
811 
SetSocks4(bool x)812 void Socket::SetSocks4(bool x)
813 {
814 	m_bSocks4 = x;
815 }
816 
817 
SetSocks4Host(ipaddr_t a)818 void Socket::SetSocks4Host(ipaddr_t a)
819 {
820 	m_socks4_host = a;
821 }
822 
823 
SetSocks4Port(port_t p)824 void Socket::SetSocks4Port(port_t p)
825 {
826 	m_socks4_port = p;
827 }
828 
829 
SetSocks4Userid(const std::string & x)830 void Socket::SetSocks4Userid(const std::string& x)
831 {
832 	m_socks4_userid = x;
833 }
834 
835 
GetSocks4Host()836 ipaddr_t Socket::GetSocks4Host()
837 {
838 	return m_socks4_host;
839 }
840 
841 
GetSocks4Port()842 port_t Socket::GetSocks4Port()
843 {
844 	return m_socks4_port;
845 }
846 
847 
GetSocks4Userid()848 const std::string& Socket::GetSocks4Userid()
849 {
850 	return m_socks4_userid;
851 }
852 #endif // ENABLE_SOCKS4
853 
854 
855 #ifdef ENABLE_DETACH
Detach()856 bool Socket::Detach()
857 {
858 	if (!DeleteByHandler())
859 		return false;
860 	if (m_pThread)
861 		return false;
862 	if (m_detached)
863 		return false;
864 	SetDetach();
865 	return true;
866 }
867 
868 
DetachSocket()869 void Socket::DetachSocket()
870 {
871 	SetDetached();
872 	m_pThread = new SocketThread(this);
873 	m_pThread -> SetRelease(true);
874 }
875 
876 
OnDetached()877 void Socket::OnDetached()
878 {
879 }
880 
881 
SetDetach(bool x)882 void Socket::SetDetach(bool x)
883 {
884 	m_detach = x;
885 	if (x)
886 		Handler().SetDetach();
887 }
888 
889 
IsDetach()890 bool Socket::IsDetach()
891 {
892 	return m_detach;
893 }
894 
895 
SetDetached(bool x)896 void Socket::SetDetached(bool x)
897 {
898 	m_detached = x;
899 }
900 
901 
IsDetached() const902 bool Socket::IsDetached() const
903 {
904 	return m_detached;
905 }
906 
907 
SetSlaveHandler(ISocketHandler * p)908 void Socket::SetSlaveHandler(ISocketHandler *p)
909 {
910 	m_slave_handler = p;
911 }
912 
913 
914 #endif // ENABLE_DETACH
915 
916 
917 #ifdef ENABLE_RESOLVER
Resolve(const std::string & host,port_t port)918 int Socket::Resolve(const std::string& host,port_t port)
919 {
920 	return Handler().Resolve(this, host, port);
921 }
922 
923 
924 #ifdef ENABLE_IPV6
Resolve6(const std::string & host,port_t port)925 int Socket::Resolve6(const std::string& host,port_t port)
926 {
927 	return Handler().Resolve6(this, host, port);
928 }
929 #endif
930 
931 
Resolve(ipaddr_t a)932 int Socket::Resolve(ipaddr_t a)
933 {
934 	return Handler().Resolve(this, a);
935 }
936 
937 
938 #ifdef ENABLE_IPV6
Resolve(in6_addr & a)939 int Socket::Resolve(in6_addr& a)
940 {
941 	return Handler().Resolve(this, a);
942 }
943 #endif
944 
945 
OnResolved(int,ipaddr_t,port_t)946 void Socket::OnResolved(int,ipaddr_t,port_t)
947 {
948 }
949 
950 
951 #ifdef ENABLE_IPV6
OnResolved(int,in6_addr &,port_t)952 void Socket::OnResolved(int,in6_addr&,port_t)
953 {
954 }
955 #endif
956 
957 
OnReverseResolved(int,const std::string &)958 void Socket::OnReverseResolved(int,const std::string&)
959 {
960 }
961 
962 
OnResolveFailed(int)963 void Socket::OnResolveFailed(int)
964 {
965 }
966 #endif // ENABLE_RESOLVER
967 
968 
969 /* IP options */
970 
971 
SetIpOptions(const void * p,socklen_t len)972 bool Socket::SetIpOptions(const void *p, socklen_t len)
973 {
974 #ifdef IP_OPTIONS
975 	if (setsockopt(GetSocket(), IPPROTO_IP, IP_OPTIONS, (char *)p, len) == -1)
976 	{
977 		Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_OPTIONS)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
978 		return false;
979 	}
980 	return true;
981 #else
982 	Handler().LogError(this, "ip option not available", 0, "IP_OPTIONS", LOG_LEVEL_INFO);
983 	return false;
984 #endif
985 }
986 
987 
988 #ifdef IP_PKTINFO
SetIpPktinfo(bool x)989 bool Socket::SetIpPktinfo(bool x)
990 {
991 	int optval = x ? 1 : 0;
992 	if (setsockopt(GetSocket(), IPPROTO_IP, IP_PKTINFO, (char *)&optval, sizeof(optval)) == -1)
993 	{
994 		Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_PKTINFO)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
995 		return false;
996 	}
997 	return true;
998 }
999 #endif
1000 
1001 
1002 #ifdef IP_RECVTOS
SetIpRecvTOS(bool x)1003 bool Socket::SetIpRecvTOS(bool x)
1004 {
1005 	int optval = x ? 1 : 0;
1006 	if (setsockopt(GetSocket(), IPPROTO_IP, IP_RECVTOS, (char *)&optval, sizeof(optval)) == -1)
1007 	{
1008 		Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RECVTOS)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1009 		return false;
1010 	}
1011 	return true;
1012 }
1013 #endif
1014 
1015 
1016 #ifdef IP_RECVTTL
SetIpRecvTTL(bool x)1017 bool Socket::SetIpRecvTTL(bool x)
1018 {
1019 	int optval = x ? 1 : 0;
1020 	if (setsockopt(GetSocket(), IPPROTO_IP, IP_RECVTTL, (char *)&optval, sizeof(optval)) == -1)
1021 	{
1022 		Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RECVTTL)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1023 		return false;
1024 	}
1025 	return true;
1026 }
1027 #endif
1028 
1029 
1030 #ifdef IP_RECVOPTS
SetIpRecvopts(bool x)1031 bool Socket::SetIpRecvopts(bool x)
1032 {
1033 	int optval = x ? 1 : 0;
1034 	if (setsockopt(GetSocket(), IPPROTO_IP, IP_RECVOPTS, (char *)&optval, sizeof(optval)) == -1)
1035 	{
1036 		Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RECVOPTS)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1037 		return false;
1038 	}
1039 	return true;
1040 }
1041 #endif
1042 
1043 
1044 #ifdef IP_RETOPTS
SetIpRetopts(bool x)1045 bool Socket::SetIpRetopts(bool x)
1046 {
1047 	int optval = x ? 1 : 0;
1048 	if (setsockopt(GetSocket(), IPPROTO_IP, IP_RETOPTS, (char *)&optval, sizeof(optval)) == -1)
1049 	{
1050 		Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RETOPTS)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1051 		return false;
1052 	}
1053 	return true;
1054 }
1055 #endif
1056 
1057 
SetIpTOS(unsigned char tos)1058 bool Socket::SetIpTOS(unsigned char tos)
1059 {
1060 #ifdef IP_TOS
1061 	if (setsockopt(GetSocket(), IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(tos)) == -1)
1062 	{
1063 		Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_TOS)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1064 		return false;
1065 	}
1066 	return true;
1067 #else
1068 	Handler().LogError(this, "ip option not available", 0, "IP_TOS", LOG_LEVEL_INFO);
1069 	return false;
1070 #endif
1071 }
1072 
1073 
IpTOS()1074 unsigned char Socket::IpTOS()
1075 {
1076 	unsigned char tos = 0;
1077 #ifdef IP_TOS
1078 	socklen_t len = sizeof(tos);
1079 	if (getsockopt(GetSocket(), IPPROTO_IP, IP_TOS, (char *)&tos, &len) == -1)
1080 	{
1081 		Handler().LogError(this, "getsockopt(IPPROTO_IP, IP_TOS)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1082 	}
1083 #else
1084 	Handler().LogError(this, "ip option not available", 0, "IP_TOS", LOG_LEVEL_INFO);
1085 #endif
1086 	return tos;
1087 }
1088 
1089 
SetIpTTL(int ttl)1090 bool Socket::SetIpTTL(int ttl)
1091 {
1092 #ifdef IP_TTL
1093 	if (setsockopt(GetSocket(), IPPROTO_IP, IP_TTL, (char *)&ttl, sizeof(ttl)) == -1)
1094 	{
1095 		Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_TTL)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1096 		return false;
1097 	}
1098 	return true;
1099 #else
1100 	Handler().LogError(this, "ip option not available", 0, "IP_TTL", LOG_LEVEL_INFO);
1101 	return false;
1102 #endif
1103 }
1104 
1105 
IpTTL()1106 int Socket::IpTTL()
1107 {
1108 	int ttl = 0;
1109 #ifdef IP_TTL
1110 	socklen_t len = sizeof(ttl);
1111 	if (getsockopt(GetSocket(), IPPROTO_IP, IP_TTL, (char *)&ttl, &len) == -1)
1112 	{
1113 		Handler().LogError(this, "getsockopt(IPPROTO_IP, IP_TTL)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1114 	}
1115 #else
1116 	Handler().LogError(this, "ip option not available", 0, "IP_TTL", LOG_LEVEL_INFO);
1117 #endif
1118 	return ttl;
1119 }
1120 
1121 
SetIpHdrincl(bool x)1122 bool Socket::SetIpHdrincl(bool x)
1123 {
1124 #ifdef IP_HDRINCL
1125 	int optval = x ? 1 : 0;
1126 	if (setsockopt(GetSocket(), IPPROTO_IP, IP_HDRINCL, (char *)&optval, sizeof(optval)) == -1)
1127 	{
1128 		Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_HDRINCL)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1129 		return false;
1130 	}
1131 	return true;
1132 #else
1133 	Handler().LogError(this, "ip option not available", 0, "IP_HDRINCL", LOG_LEVEL_INFO);
1134 	return false;
1135 #endif
1136 }
1137 
1138 
1139 #ifdef IP_RECVERR
SetIpRecverr(bool x)1140 bool Socket::SetIpRecverr(bool x)
1141 {
1142 	int optval = x ? 1 : 0;
1143 	if (setsockopt(GetSocket(), IPPROTO_IP, IP_RECVERR, (char *)&optval, sizeof(optval)) == -1)
1144 	{
1145 		Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RECVERR)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1146 		return false;
1147 	}
1148 	return true;
1149 }
1150 #endif
1151 
1152 
1153 #ifdef IP_MTU_DISCOVER
SetIpMtudiscover(bool x)1154 bool Socket::SetIpMtudiscover(bool x)
1155 {
1156 	int optval = x ? 1 : 0;
1157 	if (setsockopt(GetSocket(), IPPROTO_IP, IP_MTU_DISCOVER, (char *)&optval, sizeof(optval)) == -1)
1158 	{
1159 		Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_MTU_DISCOVER)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1160 		return false;
1161 	}
1162 	return true;
1163 }
1164 #endif
1165 
1166 
1167 #ifdef IP_MTU
IpMtu()1168 int Socket::IpMtu()
1169 {
1170 	int mtu = 0;
1171 	socklen_t len = sizeof(mtu);
1172 	if (getsockopt(GetSocket(), IPPROTO_IP, IP_MTU, (char *)&mtu, &len) == -1)
1173 	{
1174 		Handler().LogError(this, "getsockopt(IPPROTO_IP, IP_MTU)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1175 	}
1176 	return mtu;
1177 }
1178 #endif
1179 
1180 
1181 #ifdef IP_ROUTER_ALERT
SetIpRouterAlert(bool x)1182 bool Socket::SetIpRouterAlert(bool x)
1183 {
1184 	int optval = x ? 1 : 0;
1185 	if (setsockopt(GetSocket(), IPPROTO_IP, IP_ROUTER_ALERT, (char *)&optval, sizeof(optval)) == -1)
1186 	{
1187 		Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_ROUTER_ALERT)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1188 		return false;
1189 	}
1190 	return true;
1191 }
1192 #endif
1193 
1194 
SetIpMulticastTTL(int ttl)1195 bool Socket::SetIpMulticastTTL(int ttl)
1196 {
1197 #ifdef IP_MULTICAST_TTL
1198 	if (setsockopt(GetSocket(), IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(ttl)) == -1)
1199 	{
1200 		Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_MULTICAST_TTL)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1201 		return false;
1202 	}
1203 	return true;
1204 #else
1205 	Handler().LogError(this, "ip option not available", 0, "IP_MULTICAST_TTL", LOG_LEVEL_INFO);
1206 	return false;
1207 #endif
1208 }
1209 
1210 
IpMulticastTTL()1211 int Socket::IpMulticastTTL()
1212 {
1213 	int ttl = 0;
1214 #ifdef IP_MULTICAST_TTL
1215 	socklen_t len = sizeof(ttl);
1216 	if (getsockopt(GetSocket(), IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, &len) == -1)
1217 	{
1218 		Handler().LogError(this, "getsockopt(IPPROTO_IP, IP_MULTICAST_TTL)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1219 	}
1220 #else
1221 	Handler().LogError(this, "ip option not available", 0, "IP_MULTICAST_TTL", LOG_LEVEL_INFO);
1222 #endif
1223 	return ttl;
1224 }
1225 
1226 
SetMulticastLoop(bool x)1227 bool Socket::SetMulticastLoop(bool x)
1228 {
1229 #ifdef IP_MULTICAST_LOOP
1230 	int optval = x ? 1 : 0;
1231 	if (setsockopt(GetSocket(), IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&optval, sizeof(optval)) == -1)
1232 	{
1233 		Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_MULTICAST_LOOP)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1234 		return false;
1235 	}
1236 	return true;
1237 #else
1238 	Handler().LogError(this, "ip option not available", 0, "IP_MULTICAST_LOOP", LOG_LEVEL_INFO);
1239 	return false;
1240 #endif
1241 }
1242 
1243 
1244 #ifdef LINUX
IpAddMembership(struct ip_mreqn & ref)1245 bool Socket::IpAddMembership(struct ip_mreqn& ref)
1246 {
1247 #ifdef IP_ADD_MEMBERSHIP
1248 	if (setsockopt(GetSocket(), IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&ref, sizeof(struct ip_mreqn)) == -1)
1249 	{
1250 		Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1251 		return false;
1252 	}
1253 	return true;
1254 #else
1255 	Handler().LogError(this, "ip option not available", 0, "IP_ADD_MEMBERSHIP", LOG_LEVEL_INFO);
1256 	return false;
1257 #endif
1258 }
1259 #endif
1260 
1261 
IpAddMembership(struct ip_mreq & ref)1262 bool Socket::IpAddMembership(struct ip_mreq& ref)
1263 {
1264 #ifdef IP_ADD_MEMBERSHIP
1265 	if (setsockopt(GetSocket(), IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&ref, sizeof(struct ip_mreq)) == -1)
1266 	{
1267 		Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1268 		return false;
1269 	}
1270 	return true;
1271 #else
1272 	Handler().LogError(this, "ip option not available", 0, "IP_ADD_MEMBERSHIP", LOG_LEVEL_INFO);
1273 	return false;
1274 #endif
1275 }
1276 
1277 
1278 #ifdef LINUX
IpDropMembership(struct ip_mreqn & ref)1279 bool Socket::IpDropMembership(struct ip_mreqn& ref)
1280 {
1281 #ifdef IP_DROP_MEMBERSHIP
1282 	if (setsockopt(GetSocket(), IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *)&ref, sizeof(struct ip_mreqn)) == -1)
1283 	{
1284 		Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_DROP_MEMBERSHIP)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1285 		return false;
1286 	}
1287 	return true;
1288 #else
1289 	Handler().LogError(this, "ip option not available", 0, "IP_DROP_MEMBERSHIP", LOG_LEVEL_INFO);
1290 	return false;
1291 #endif
1292 }
1293 #endif
1294 
1295 
IpDropMembership(struct ip_mreq & ref)1296 bool Socket::IpDropMembership(struct ip_mreq& ref)
1297 {
1298 #ifdef IP_DROP_MEMBERSHIP
1299 	if (setsockopt(GetSocket(), IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *)&ref, sizeof(struct ip_mreq)) == -1)
1300 	{
1301 		Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_DROP_MEMBERSHIP)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1302 		return false;
1303 	}
1304 	return true;
1305 #else
1306 	Handler().LogError(this, "ip option not available", 0, "IP_DROP_MEMBERSHIP", LOG_LEVEL_INFO);
1307 	return false;
1308 #endif
1309 }
1310 
1311 
1312 /* SOCKET options */
1313 
1314 
SetSoReuseaddr(bool x)1315 bool Socket::SetSoReuseaddr(bool x)
1316 {
1317 #ifdef SO_REUSEADDR
1318 	int optval = x ? 1 : 0;
1319 	if (setsockopt(GetSocket(), SOL_SOCKET, SO_REUSEADDR, (char *)&optval, sizeof(optval)) == -1)
1320 	{
1321 		Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_REUSEADDR)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1322 		return false;
1323 	}
1324 	return true;
1325 #else
1326 	Handler().LogError(this, "socket option not available", 0, "SO_REUSEADDR", LOG_LEVEL_INFO);
1327 	return false;
1328 #endif
1329 }
1330 
1331 
SetSoKeepalive(bool x)1332 bool Socket::SetSoKeepalive(bool x)
1333 {
1334 #ifdef SO_KEEPALIVE
1335 	int optval = x ? 1 : 0;
1336 	if (setsockopt(GetSocket(), SOL_SOCKET, SO_KEEPALIVE, (char *)&optval, sizeof(optval)) == -1)
1337 	{
1338 		Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_KEEPALIVE)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1339 		return false;
1340 	}
1341 	return true;
1342 #else
1343 	Handler().LogError(this, "socket option not available", 0, "SO_KEEPALIVE", LOG_LEVEL_INFO);
1344 	return false;
1345 #endif
1346 }
1347 
1348 
1349 #ifdef SO_NOSIGPIPE
SetSoNosigpipe(bool x)1350 bool Socket::SetSoNosigpipe(bool x)
1351 {
1352 	int optval = x ? 1 : 0;
1353 	if (setsockopt(GetSocket(), SOL_SOCKET, SO_NOSIGPIPE, (char *)&optval, sizeof(optval)) == -1)
1354 	{
1355 		Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_NOSIGPIPE)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1356 		return false;
1357 	}
1358 	return true;
1359 }
1360 #endif
1361 
1362 
SoAcceptconn()1363 bool Socket::SoAcceptconn()
1364 {
1365 	int value = 0;
1366 #ifdef SO_ACCEPTCONN
1367 	socklen_t len = sizeof(value);
1368 	if (getsockopt(GetSocket(), SOL_SOCKET, SO_ACCEPTCONN, (char *)&value, &len) == -1)
1369 	{
1370 		Handler().LogError(this, "getsockopt(SOL_SOCKET, SO_ACCEPTCONN)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1371 	}
1372 #else
1373 	Handler().LogError(this, "socket option not available", 0, "SO_ACCEPTCONN", LOG_LEVEL_INFO);
1374 #endif
1375 	return value ? true : false;
1376 }
1377 
1378 
1379 #ifdef SO_BSDCOMPAT
SetSoBsdcompat(bool x)1380 bool Socket::SetSoBsdcompat(bool x)
1381 {
1382 	int optval = x ? 1 : 0;
1383 	if (setsockopt(GetSocket(), SOL_SOCKET, SO_BSDCOMPAT, (char *)&optval, sizeof(optval)) == -1)
1384 	{
1385 		Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_BSDCOMPAT)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1386 		return false;
1387 	}
1388 	return true;
1389 }
1390 #endif
1391 
1392 
1393 #ifdef SO_BINDTODEVICE
SetSoBindtodevice(const std::string & intf)1394 bool Socket::SetSoBindtodevice(const std::string& intf)
1395 {
1396 	if (setsockopt(GetSocket(), SOL_SOCKET, SO_BINDTODEVICE, (char *)intf.c_str(), intf.size()) == -1)
1397 	{
1398 		Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_BINDTODEVICE)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1399 		return false;
1400 	}
1401 	return true;
1402 }
1403 #endif
1404 
1405 
SetSoBroadcast(bool x)1406 bool Socket::SetSoBroadcast(bool x)
1407 {
1408 #ifdef SO_BROADCAST
1409 	int optval = x ? 1 : 0;
1410 	if (setsockopt(GetSocket(), SOL_SOCKET, SO_BROADCAST, (char *)&optval, sizeof(optval)) == -1)
1411 	{
1412 		Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_BROADCAST)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1413 		return false;
1414 	}
1415 	return true;
1416 #else
1417 	Handler().LogError(this, "socket option not available", 0, "SO_BROADCAST", LOG_LEVEL_INFO);
1418 	return false;
1419 #endif
1420 }
1421 
1422 
SetSoDebug(bool x)1423 bool Socket::SetSoDebug(bool x)
1424 {
1425 #ifdef SO_DEBUG
1426 	int optval = x ? 1 : 0;
1427 	if (setsockopt(GetSocket(), SOL_SOCKET, SO_DEBUG, (char *)&optval, sizeof(optval)) == -1)
1428 	{
1429 		Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_DEBUG)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1430 		return false;
1431 	}
1432 	return true;
1433 #else
1434 	Handler().LogError(this, "socket option not available", 0, "SO_DEBUG", LOG_LEVEL_INFO);
1435 	return false;
1436 #endif
1437 }
1438 
1439 
SoError()1440 int Socket::SoError()
1441 {
1442 	int value = 0;
1443 #ifdef SO_ERROR
1444 	socklen_t len = sizeof(value);
1445 	if (getsockopt(GetSocket(), SOL_SOCKET, SO_ERROR, (char *)&value, &len) == -1)
1446 	{
1447 		Handler().LogError(this, "getsockopt(SOL_SOCKET, SO_ERROR)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1448 	}
1449 #else
1450 	Handler().LogError(this, "socket option not available", 0, "SO_ERROR", LOG_LEVEL_INFO);
1451 #endif
1452 	return value;
1453 }
1454 
1455 
SetSoDontroute(bool x)1456 bool Socket::SetSoDontroute(bool x)
1457 {
1458 #ifdef SO_DONTROUTE
1459 	int optval = x ? 1 : 0;
1460 	if (setsockopt(GetSocket(), SOL_SOCKET, SO_DONTROUTE, (char *)&optval, sizeof(optval)) == -1)
1461 	{
1462 		Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_DONTROUTE)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1463 		return false;
1464 	}
1465 	return true;
1466 #else
1467 	Handler().LogError(this, "socket option not available", 0, "SO_DONTROUTE", LOG_LEVEL_INFO);
1468 	return false;
1469 #endif
1470 }
1471 
1472 
SetSoLinger(int onoff,int linger)1473 bool Socket::SetSoLinger(int onoff, int linger)
1474 {
1475 #ifdef SO_LINGER
1476 	struct linger stl;
1477 	stl.l_onoff = onoff;
1478 	stl.l_linger = linger;
1479 	if (setsockopt(GetSocket(), SOL_SOCKET, SO_LINGER, (char *)&stl, sizeof(stl)) == -1)
1480 	{
1481 		Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_LINGER)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1482 		return false;
1483 	}
1484 	return true;
1485 #else
1486 	Handler().LogError(this, "socket option not available", 0, "SO_LINGER", LOG_LEVEL_INFO);
1487 	return false;
1488 #endif
1489 }
1490 
1491 
SetSoOobinline(bool x)1492 bool Socket::SetSoOobinline(bool x)
1493 {
1494 #ifdef SO_OOBINLINE
1495 	int optval = x ? 1 : 0;
1496 	if (setsockopt(GetSocket(), SOL_SOCKET, SO_OOBINLINE, (char *)&optval, sizeof(optval)) == -1)
1497 	{
1498 		Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_OOBINLINE)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1499 		return false;
1500 	}
1501 	return true;
1502 #else
1503 	Handler().LogError(this, "socket option not available", 0, "SO_OOBINLINE", LOG_LEVEL_INFO);
1504 	return false;
1505 #endif
1506 }
1507 
1508 
1509 #ifdef SO_PASSCRED
SetSoPasscred(bool x)1510 bool Socket::SetSoPasscred(bool x)
1511 {
1512 	int optval = x ? 1 : 0;
1513 	if (setsockopt(GetSocket(), SOL_SOCKET, SO_PASSCRED, (char *)&optval, sizeof(optval)) == -1)
1514 	{
1515 		Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_PASSCRED)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1516 		return false;
1517 	}
1518 	return true;
1519 }
1520 #endif
1521 
1522 
1523 #ifdef SO_PEERCRED
SoPeercred(struct ucred & ucr)1524 bool Socket::SoPeercred(struct ucred& ucr)
1525 {
1526 	if (setsockopt(GetSocket(), SOL_SOCKET, SO_PEERCRED, (char *)&ucr, sizeof(ucr)) == -1)
1527 	{
1528 		Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_PEERCRED)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1529 		return false;
1530 	}
1531 	return true;
1532 }
1533 #endif
1534 
1535 
1536 #ifdef SO_PRIORITY
SetSoPriority(int x)1537 bool Socket::SetSoPriority(int x)
1538 {
1539 	if (setsockopt(GetSocket(), SOL_SOCKET, SO_PRIORITY, (char *)&x, sizeof(x)) == -1)
1540 	{
1541 		Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_PRIORITY)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1542 		return false;
1543 	}
1544 	return true;
1545 }
1546 #endif
1547 
1548 
SetSoRcvlowat(int x)1549 bool Socket::SetSoRcvlowat(int x)
1550 {
1551 #ifdef SO_RCVLOWAT
1552 	if (setsockopt(GetSocket(), SOL_SOCKET, SO_RCVLOWAT, (char *)&x, sizeof(x)) == -1)
1553 	{
1554 		Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_RCVLOWAT)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1555 		return false;
1556 	}
1557 	return true;
1558 #else
1559 	Handler().LogError(this, "socket option not available", 0, "SO_RCVLOWAT", LOG_LEVEL_INFO);
1560 	return false;
1561 #endif
1562 }
1563 
1564 
SetSoSndlowat(int x)1565 bool Socket::SetSoSndlowat(int x)
1566 {
1567 #ifdef SO_SNDLOWAT
1568 	if (setsockopt(GetSocket(), SOL_SOCKET, SO_SNDLOWAT, (char *)&x, sizeof(x)) == -1)
1569 	{
1570 		Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_SNDLOWAT)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1571 		return false;
1572 	}
1573 	return true;
1574 #else
1575 	Handler().LogError(this, "socket option not available", 0, "SO_SNDLOWAT", LOG_LEVEL_INFO);
1576 	return false;
1577 #endif
1578 }
1579 
1580 
SetSoRcvtimeo(struct timeval & tv)1581 bool Socket::SetSoRcvtimeo(struct timeval& tv)
1582 {
1583 #ifdef SO_RCVTIMEO
1584 	if (setsockopt(GetSocket(), SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)) == -1)
1585 	{
1586 		Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_RCVTIMEO)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1587 		return false;
1588 	}
1589 	return true;
1590 #else
1591 	Handler().LogError(this, "socket option not available", 0, "SO_RCVTIMEO", LOG_LEVEL_INFO);
1592 	return false;
1593 #endif
1594 }
1595 
1596 
SetSoSndtimeo(struct timeval & tv)1597 bool Socket::SetSoSndtimeo(struct timeval& tv)
1598 {
1599 #ifdef SO_SNDTIMEO
1600 	if (setsockopt(GetSocket(), SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(tv)) == -1)
1601 	{
1602 		Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_SNDTIMEO)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1603 		return false;
1604 	}
1605 	return true;
1606 #else
1607 	Handler().LogError(this, "socket option not available", 0, "SO_SNDTIMEO", LOG_LEVEL_INFO);
1608 	return false;
1609 #endif
1610 }
1611 
1612 
SetSoRcvbuf(int x)1613 bool Socket::SetSoRcvbuf(int x)
1614 {
1615 #ifdef SO_RCVBUF
1616 	if (setsockopt(GetSocket(), SOL_SOCKET, SO_RCVBUF, (char *)&x, sizeof(x)) == -1)
1617 	{
1618 		Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_RCVBUF)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1619 		return false;
1620 	}
1621 	return true;
1622 #else
1623 	Handler().LogError(this, "socket option not available", 0, "SO_RCVBUF", LOG_LEVEL_INFO);
1624 	return false;
1625 #endif
1626 }
1627 
1628 
SoRcvbuf()1629 int Socket::SoRcvbuf()
1630 {
1631 	int value = 0;
1632 #ifdef SO_RCVBUF
1633 	socklen_t len = sizeof(value);
1634 	if (getsockopt(GetSocket(), SOL_SOCKET, SO_RCVBUF, (char *)&value, &len) == -1)
1635 	{
1636 		Handler().LogError(this, "getsockopt(SOL_SOCKET, SO_RCVBUF)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1637 	}
1638 #else
1639 	Handler().LogError(this, "socket option not available", 0, "SO_RCVBUF", LOG_LEVEL_INFO);
1640 #endif
1641 	return value;
1642 }
1643 
1644 
1645 #ifdef SO_RCVBUFFORCE
SetSoRcvbufforce(int x)1646 bool Socket::SetSoRcvbufforce(int x)
1647 {
1648 	if (setsockopt(GetSocket(), SOL_SOCKET, SO_RCVBUFFORCE, (char *)&x, sizeof(x)) == -1)
1649 	{
1650 		Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_RCVBUFFORCE)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1651 		return false;
1652 	}
1653 	return true;
1654 }
1655 #endif
1656 
1657 
SetSoSndbuf(int x)1658 bool Socket::SetSoSndbuf(int x)
1659 {
1660 #ifdef SO_SNDBUF
1661 	if (setsockopt(GetSocket(), SOL_SOCKET, SO_SNDBUF, (char *)&x, sizeof(x)) == -1)
1662 	{
1663 		Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_SNDBUF)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1664 		return false;
1665 	}
1666 	return true;
1667 #else
1668 	Handler().LogError(this, "socket option not available", 0, "SO_SNDBUF", LOG_LEVEL_INFO);
1669 	return false;
1670 #endif
1671 }
1672 
1673 
SoSndbuf()1674 int Socket::SoSndbuf()
1675 {
1676 	int value = 0;
1677 #ifdef SO_SNDBUF
1678 	socklen_t len = sizeof(value);
1679 	if (getsockopt(GetSocket(), SOL_SOCKET, SO_SNDBUF, (char *)&value, &len) == -1)
1680 	{
1681 		Handler().LogError(this, "getsockopt(SOL_SOCKET, SO_SNDBUF)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1682 	}
1683 #else
1684 	Handler().LogError(this, "socket option not available", 0, "SO_SNDBUF", LOG_LEVEL_INFO);
1685 #endif
1686 	return value;
1687 }
1688 
1689 
1690 #ifdef SO_SNDBUFFORCE
SetSoSndbufforce(int x)1691 bool Socket::SetSoSndbufforce(int x)
1692 {
1693 	if (setsockopt(GetSocket(), SOL_SOCKET, SO_SNDBUFFORCE, (char *)&x, sizeof(x)) == -1)
1694 	{
1695 		Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_SNDBUFFORCE)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1696 		return false;
1697 	}
1698 	return true;
1699 }
1700 #endif
1701 
1702 
1703 #ifdef SO_TIMESTAMP
SetSoTimestamp(bool x)1704 bool Socket::SetSoTimestamp(bool x)
1705 {
1706 	int optval = x ? 1 : 0;
1707 	if (setsockopt(GetSocket(), SOL_SOCKET, SO_TIMESTAMP, (char *)&optval, sizeof(optval)) == -1)
1708 	{
1709 		Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_TIMESTAMP)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1710 		return false;
1711 	}
1712 	return true;
1713 }
1714 #endif
1715 
1716 
SoType()1717 int Socket::SoType()
1718 {
1719 	int value = 0;
1720 #ifdef SO_TYPE
1721 	socklen_t len = sizeof(value);
1722 	if (getsockopt(GetSocket(), SOL_SOCKET, SO_TYPE, (char *)&value, &len) == -1)
1723 	{
1724 		Handler().LogError(this, "getsockopt(SOL_SOCKET, SO_TYPE)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
1725 	}
1726 #else
1727 	Handler().LogError(this, "socket option not available", 0, "SO_TYPE", LOG_LEVEL_INFO);
1728 #endif
1729 	return value;
1730 }
1731 
1732 
SetTimeout(time_t secs)1733 void Socket::SetTimeout(time_t secs)
1734 {
1735 	if (!secs)
1736 	{
1737 		m_timeout_start = 0;
1738 		m_timeout_limit = 0;
1739 		return;
1740 	}
1741 	m_timeout_start = time(NULL);
1742 	m_timeout_limit = secs;
1743 	Handler().SetTimeout();
1744 }
1745 
1746 
CheckTimeout()1747 bool Socket::CheckTimeout()
1748 {
1749 	return m_timeout_start > 0 && m_timeout_limit > 0;
1750 }
1751 
1752 
OnTimeout()1753 void Socket::OnTimeout()
1754 {
1755 }
1756 
1757 
OnConnectTimeout()1758 void Socket::OnConnectTimeout()
1759 {
1760 }
1761 
1762 
Timeout(time_t tnow)1763 bool Socket::Timeout(time_t tnow)
1764 {
1765 	if (m_timeout_start > 0 && tnow - m_timeout_start > m_timeout_limit)
1766 		return true;
1767 	return false;
1768 }
1769 
1770 
1771 /** Returns local port number for bound socket file descriptor. */
GetSockPort()1772 port_t Socket::GetSockPort()
1773 {
1774 #ifdef ENABLE_IPV6
1775 #ifdef IPPROTO_IPV6
1776 	if (IsIpv6())
1777 	{
1778 		struct sockaddr_in6 sa;
1779 		socklen_t sockaddr_length = sizeof(struct sockaddr_in6);
1780 		if (getsockname(GetSocket(), (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length) == -1)
1781 			memset(&sa, 0, sizeof(sa));
1782 		return ntohs(sa.sin6_port);
1783 	}
1784 #endif
1785 #endif
1786 	struct sockaddr_in sa;
1787 	socklen_t sockaddr_length = sizeof(struct sockaddr_in);
1788 	if (getsockname(GetSocket(), (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length) == -1)
1789 		memset(&sa, 0, sizeof(sa));
1790 	return ntohs(sa.sin_port);
1791 }
1792 
1793 
1794 /** Returns local ipv4 address for bound socket file descriptor. */
GetSockIP4()1795 ipaddr_t Socket::GetSockIP4()
1796 {
1797 #ifdef ENABLE_IPV6
1798 #ifdef IPPROTO_IPV6
1799 	if (IsIpv6())
1800 	{
1801 		return 0;
1802 	}
1803 #endif
1804 #endif
1805 	struct sockaddr_in sa;
1806 	socklen_t sockaddr_length = sizeof(struct sockaddr_in);
1807 	if (getsockname(GetSocket(), (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length) == -1)
1808 		memset(&sa, 0, sizeof(sa));
1809 	ipaddr_t a;
1810 	memcpy(&a, &sa.sin_addr, 4);
1811 	return a;
1812 }
1813 
1814 
1815 /** Returns local ipv4 address as text for bound socket file descriptor. */
GetSockAddress()1816 std::string Socket::GetSockAddress()
1817 {
1818 #ifdef ENABLE_IPV6
1819 #ifdef IPPROTO_IPV6
1820 	if (IsIpv6())
1821 	{
1822 		return "";
1823 	}
1824 #endif
1825 #endif
1826 	struct sockaddr_in sa;
1827 	socklen_t sockaddr_length = sizeof(struct sockaddr_in);
1828 	if (getsockname(GetSocket(), (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length) == -1)
1829 		memset(&sa, 0, sizeof(sa));
1830 	Ipv4Address addr( sa );
1831 	return addr.Convert();
1832 }
1833 
1834 
1835 #ifdef ENABLE_IPV6
1836 #ifdef IPPROTO_IPV6
1837 /** Returns local ipv6 address for bound socket file descriptor. */
GetSockIP6()1838 struct in6_addr Socket::GetSockIP6()
1839 {
1840 	if (IsIpv6())
1841 	{
1842 		struct sockaddr_in6 sa;
1843 		socklen_t sockaddr_length = sizeof(struct sockaddr_in6);
1844 		if (getsockname(GetSocket(), (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length) == -1)
1845 			memset(&sa, 0, sizeof(sa));
1846 		return sa.sin6_addr;
1847 	}
1848 	struct in6_addr a;
1849 	memset(&a, 0, sizeof(a));
1850 	return a;
1851 }
1852 
1853 
1854 /** Returns local ipv6 address as text for bound socket file descriptor. */
GetSockAddress6()1855 std::string Socket::GetSockAddress6()
1856 {
1857 	if (IsIpv6())
1858 	{
1859 		struct sockaddr_in6 sa;
1860 		socklen_t sockaddr_length = sizeof(struct sockaddr_in6);
1861 		if (getsockname(GetSocket(), (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length) == -1)
1862 			memset(&sa, 0, sizeof(sa));
1863 		Ipv6Address addr( sa );
1864 		return addr.Convert();
1865 	}
1866 	return "";
1867 }
1868 #endif
1869 #endif
1870 
1871 
1872 #ifdef SOCKETS_NAMESPACE
1873 }
1874 #endif
1875 
1876