3 ** \author grymse@alhem.net
6 Copyright (C) 2004-2007 Anders Hedstrom
8 This library is made available under the terms of the GNU GPL.
10 If you would like to use this library in a closed-source application,
11 a separate license agreement is available. For information about
12 the closed-source license agreement for the C++ sockets library,
13 please visit http://www.alhem.net/Sockets/license.html and/or
14 email license@alhem.net.
16 This program is free software; you can redistribute it and/or
17 modify it under the terms of the GNU General Public License
18 as published by the Free Software Foundation; either version 2
19 of the License, or (at your option) any later version.
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the Free Software
28 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33 #pragma warning(disable:4786)
43 #include "ISocketHandler.h"
46 #include "SocketAddress.h"
47 #include "SocketHandler.h"
50 #define DEB(x) x; fflush(stderr);
55 #ifdef SOCKETS_NAMESPACE
56 namespace SOCKETS_NAMESPACE
{
62 WSAInitializer
Socket::m_winsock_init
;
66 Socket::Socket(ISocketHandler
& h
)
69 ,m_socket( INVALID_SOCKET
)
72 ,m_tCreate(time(NULL
))
74 ,m_b_disable_read(false)
76 ,m_b_erased_by_handler(false)
78 ,m_client_remote_address(NULL
)
79 ,m_remote_address(NULL
)
80 ,m_traffic_monitor(NULL
)
82 ,m_b_enable_ssl(false)
84 ,m_b_ssl_server(false)
97 ,m_socks4_host(h
.GetSocks4Host())
98 ,m_socks4_port(h
.GetSocks4Port())
99 ,m_socks4_userid(h
.GetSocks4Userid())
105 ,m_slave_handler(NULL
)
113 Handler().Remove(this);
114 if (m_socket
!= INVALID_SOCKET
130 void Socket::OnRead()
135 void Socket::OnWrite()
140 void Socket::OnException()
142 // %! exception doesn't always mean something bad happened, this code should be reworked
145 Handler().LogError(this, "exception on select", err
, StrError(err
), LOG_LEVEL_FATAL
);
150 void Socket::OnDelete()
155 void Socket::OnConnect()
160 void Socket::OnAccept()
167 if (m_socket
== INVALID_SOCKET
) // this could happen
169 Handler().LogError(this, "Socket::Close", 0, "file descriptor invalid", LOG_LEVEL_WARNING
);
173 if ((n
= closesocket(m_socket
)) == -1)
176 Handler().LogError(this, "close", Errno
, StrError(Errno
), LOG_LEVEL_ERROR
);
178 Handler().Set(m_socket
, false, false, false); // remove from fd_set's
179 Handler().AddList(m_socket
, LIST_CALLONCONNECT
, false);
181 Handler().AddList(m_socket
, LIST_DETACH
, false);
183 Handler().AddList(m_socket
, LIST_TIMEOUT
, false);
184 Handler().AddList(m_socket
, LIST_RETRY
, false);
185 Handler().AddList(m_socket
, LIST_CLOSE
, false);
186 m_socket
= INVALID_SOCKET
;
191 SOCKET
Socket::CreateSocket(int af
,int type
, const std::string
& protocol
)
193 struct protoent
*p
= NULL
;
197 m_socket_type
= type
;
198 m_socket_protocol
= protocol
;
202 p
= getprotobyname( protocol
.c_str() );
205 Handler().LogError(this, "getprotobyname", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
207 return INVALID_SOCKET
;
210 int protno
= p
? p
-> p_proto
: 0;
212 s
= socket(af
, type
, protno
);
213 if (s
== INVALID_SOCKET
)
215 Handler().LogError(this, "socket", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
217 return INVALID_SOCKET
;
220 OnOptions(af
, type
, protno
, s
);
221 Attach(INVALID_SOCKET
);
226 void Socket::Attach(SOCKET s
)
232 SOCKET
Socket::GetSocket()
238 void Socket::SetDeleteByHandler(bool x
)
244 bool Socket::DeleteByHandler()
250 void Socket::SetCloseAndDelete(bool x
)
254 Handler().AddList(m_socket
, LIST_CLOSE
, x
);
258 m_tClose
= time(NULL
);
264 bool Socket::CloseAndDelete()
270 void Socket::SetRemoteAddress(SocketAddress
& ad
) //struct sockaddr* sa, socklen_t l)
272 m_remote_address
= ad
.GetCopy();
276 std::auto_ptr
<SocketAddress
> Socket::GetRemoteSocketAddress()
278 return std::auto_ptr
<SocketAddress
>(m_remote_address
-> GetCopy());
282 ISocketHandler
& Socket::Handler() const
286 return *m_slave_handler
;
292 ISocketHandler
& Socket::MasterHandler() const
298 ipaddr_t
Socket::GetRemoteIP4()
304 Handler().LogError(this, "GetRemoteIP4", 0, "get ipv4 address for ipv6 socket", LOG_LEVEL_WARNING
);
307 if (m_remote_address
.get() != NULL
)
309 struct sockaddr
*p
= *m_remote_address
;
310 struct sockaddr_in
*sa
= (struct sockaddr_in
*)p
;
311 memcpy(&l
, &sa
-> sin_addr
, sizeof(struct in_addr
));
319 struct in6_addr
Socket::GetRemoteIP6()
323 Handler().LogError(this, "GetRemoteIP6", 0, "get ipv6 address for ipv4 socket", LOG_LEVEL_WARNING
);
325 struct sockaddr_in6 fail
;
326 if (m_remote_address
.get() != NULL
)
328 struct sockaddr
*p
= *m_remote_address
;
329 memcpy(&fail
, p
, sizeof(struct sockaddr_in6
));
333 memset(&fail
, 0, sizeof(struct sockaddr_in6
));
335 return fail
.sin6_addr
;
341 port_t
Socket::GetRemotePort()
343 if (!m_remote_address
.get())
347 return m_remote_address
-> GetPort();
351 std::string
Socket::GetRemoteAddress()
353 if (!m_remote_address
.get())
357 return m_remote_address
-> Convert(false);
361 std::string
Socket::GetRemoteHostname()
363 if (!m_remote_address
.get())
367 return m_remote_address
-> Reverse();
371 bool Socket::SetNonblocking(bool bNb
)
374 unsigned long l
= bNb
? 1 : 0;
375 int n
= ioctlsocket(m_socket
, FIONBIO
, &l
);
378 Handler().LogError(this, "ioctlsocket(FIONBIO)", Errno
, "");
385 if (fcntl(m_socket
, F_SETFL
, O_NONBLOCK
) == -1)
387 Handler().LogError(this, "fcntl(F_SETFL, O_NONBLOCK)", Errno
, StrError(Errno
), LOG_LEVEL_ERROR
);
393 if (fcntl(m_socket
, F_SETFL
, 0) == -1)
395 Handler().LogError(this, "fcntl(F_SETFL, 0)", Errno
, StrError(Errno
), LOG_LEVEL_ERROR
);
404 bool Socket::SetNonblocking(bool bNb
, SOCKET s
)
407 unsigned long l
= bNb
? 1 : 0;
408 int n
= ioctlsocket(s
, FIONBIO
, &l
);
411 Handler().LogError(this, "ioctlsocket(FIONBIO)", Errno
, "");
418 if (fcntl(s
, F_SETFL
, O_NONBLOCK
) == -1)
420 Handler().LogError(this, "fcntl(F_SETFL, O_NONBLOCK)", Errno
, StrError(Errno
), LOG_LEVEL_ERROR
);
426 if (fcntl(s
, F_SETFL
, 0) == -1)
428 Handler().LogError(this, "fcntl(F_SETFL, 0)", Errno
, StrError(Errno
), LOG_LEVEL_ERROR
);
437 void Socket::Set(bool bRead
, bool bWrite
, bool bException
)
439 Handler().Set(m_socket
, bRead
, bWrite
, bException
);
445 if (m_socket
!= INVALID_SOCKET
&& !CloseAndDelete())
451 void Socket::OnLine(const std::string
& )
456 void Socket::OnConnectFailed()
461 Socket
*Socket::GetParent()
467 void Socket::SetParent(Socket
*x
)
473 port_t
Socket::GetPort()
475 Handler().LogError(this, "GetPort", 0, "GetPort only implemented for ListenSocket", LOG_LEVEL_WARNING
);
480 bool Socket::OnConnectRetry()
486 #ifdef ENABLE_RECONNECT
487 void Socket::OnReconnect()
493 time_t Socket::Uptime()
495 return time(NULL
) - m_tCreate
;
500 void Socket::SetIpv6(bool x
)
506 bool Socket::IsIpv6()
513 void Socket::DisableRead(bool x
)
515 m_b_disable_read
= x
;
519 bool Socket::IsDisableRead()
521 return m_b_disable_read
;
525 void Socket::SendBuf(const char *,size_t,int)
530 void Socket::Send(const std::string
&,int)
535 void Socket::SetConnected(bool x
)
541 bool Socket::IsConnected()
547 #ifdef ENABLE_RECONNECT
548 void Socket::OnDisconnect()
554 void Socket::SetErasedByHandler(bool x
)
556 m_b_erased_by_handler
= x
;
560 bool Socket::ErasedByHandler()
562 return m_b_erased_by_handler
;
566 time_t Socket::TimeSinceClose()
568 return time(NULL
) - m_tClose
;
572 void Socket::SetClientRemoteAddress(SocketAddress
& ad
)
576 Handler().LogError(this, "SetClientRemoteAddress", 0, "remote address not valid", LOG_LEVEL_ERROR
);
578 m_client_remote_address
= ad
.GetCopy();
582 std::auto_ptr
<SocketAddress
> Socket::GetClientRemoteAddress()
584 if (!m_client_remote_address
.get())
586 Handler().LogError(this, "GetClientRemoteAddress", 0, "remote address not yet set", LOG_LEVEL_ERROR
);
588 return std::auto_ptr
<SocketAddress
>(m_client_remote_address
-> GetCopy());
592 uint64_t Socket::GetBytesSent(bool)
598 uint64_t Socket::GetBytesReceived(bool)
605 void Socket::OnSSLConnect()
610 void Socket::OnSSLAccept()
615 bool Socket::SSLNegotiate()
623 return m_b_enable_ssl
;
627 void Socket::EnableSSL(bool x
)
633 bool Socket::IsSSLNegotiate()
639 void Socket::SetSSLNegotiate(bool x
)
645 bool Socket::IsSSLServer()
647 return m_b_ssl_server
;
651 void Socket::SetSSLServer(bool x
)
657 void Socket::OnSSLConnectFailed()
662 void Socket::OnSSLAcceptFailed()
665 #endif // HAVE_OPENSSL
669 void Socket::CopyConnection(Socket
*sock
)
671 Attach( sock
-> GetSocket() );
673 SetIpv6( sock
-> IsIpv6() );
675 SetSocketType( sock
-> GetSocketType() );
676 SetSocketProtocol( sock
-> GetSocketProtocol() );
678 SetClientRemoteAddress( *sock
-> GetClientRemoteAddress() );
679 SetRemoteAddress( *sock
-> GetRemoteSocketAddress() );
683 void Socket::SetIsClient()
689 void Socket::SetSocketType(int x
)
695 int Socket::GetSocketType()
697 return m_socket_type
;
701 void Socket::SetSocketProtocol(const std::string
& x
)
703 m_socket_protocol
= x
;
707 const std::string
& Socket::GetSocketProtocol()
709 return m_socket_protocol
;
713 void Socket::SetRetain()
715 if (m_bClient
) m_bRetain
= true;
719 bool Socket::Retain()
725 void Socket::SetLost()
735 #endif // ENABLE_POOL
739 void Socket::OnSocks4Connect()
741 Handler().LogError(this, "OnSocks4Connect", 0, "Use with TcpSocket only");
745 void Socket::OnSocks4ConnectFailed()
747 Handler().LogError(this, "OnSocks4ConnectFailed", 0, "Use with TcpSocket only");
751 bool Socket::OnSocks4Read()
753 Handler().LogError(this, "OnSocks4Read", 0, "Use with TcpSocket only");
758 void Socket::SetSocks4Host(const std::string
& host
)
760 Utility::u2ip(host
, m_socks4_host
);
764 bool Socket::Socks4()
770 void Socket::SetSocks4(bool x
)
776 void Socket::SetSocks4Host(ipaddr_t a
)
782 void Socket::SetSocks4Port(port_t p
)
788 void Socket::SetSocks4Userid(const std::string
& x
)
794 ipaddr_t
Socket::GetSocks4Host()
796 return m_socks4_host
;
800 port_t
Socket::GetSocks4Port()
802 return m_socks4_port
;
806 const std::string
& Socket::GetSocks4Userid()
808 return m_socks4_userid
;
810 #endif // ENABLE_SOCKS4
814 bool Socket::Detach()
816 if (!DeleteByHandler())
827 void Socket::DetachSocket()
830 m_pThread
= new SocketThread(this);
831 m_pThread
-> SetRelease(true);
835 void Socket::OnDetached()
840 void Socket::SetDetach(bool x
)
842 Handler().AddList(m_socket
, LIST_DETACH
, x
);
847 bool Socket::IsDetach()
853 void Socket::SetDetached(bool x
)
859 const bool Socket::IsDetached() const
865 void Socket::SetSlaveHandler(ISocketHandler
*p
)
871 Socket::SocketThread::SocketThread(Socket
*p
)
875 // Creator will release
879 Socket::SocketThread::~SocketThread()
894 void Socket::SocketThread::Run()
899 m_socket
-> SetSlaveHandler(&h
);
900 m_socket
-> OnDetached();
901 while (h
.GetCount() && IsRunning())
905 // m_socket now deleted oops
906 // yeah oops m_socket delete its socket thread, that means this
907 // so Socket will no longer delete its socket thread, instead we do this:
910 #endif // ENABLE_DETACH
913 #ifdef ENABLE_RESOLVER
914 int Socket::Resolve(const std::string
& host
,port_t port
)
916 return Handler().Resolve(this, host
, port
);
921 int Socket::Resolve6(const std::string
& host
,port_t port
)
923 return Handler().Resolve6(this, host
, port
);
928 int Socket::Resolve(ipaddr_t a
)
930 return Handler().Resolve(this, a
);
935 int Socket::Resolve(in6_addr
& a
)
937 return Handler().Resolve(this, a
);
942 void Socket::OnResolved(int,ipaddr_t
,port_t
)
948 void Socket::OnResolved(int,in6_addr
&,port_t
)
954 void Socket::OnReverseResolved(int,const std::string
&)
959 void Socket::OnResolveFailed(int)
962 #endif // ENABLE_RESOLVER
968 bool Socket::SetIpOptions(const void *p
, socklen_t len
)
971 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_OPTIONS
, (char *)p
, len
) == -1)
973 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_OPTIONS)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
978 Handler().LogError(this, "ip option not available", 0, "IP_OPTIONS", LOG_LEVEL_INFO
);
985 bool Socket::SetIpPktinfo(bool x
)
987 int optval
= x
? 1 : 0;
988 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_PKTINFO
, (char *)&optval
, sizeof(optval
)) == -1)
990 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_PKTINFO)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
999 bool Socket::SetIpRecvTOS(bool x
)
1001 int optval
= x
? 1 : 0;
1002 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_RECVTOS
, (char *)&optval
, sizeof(optval
)) == -1)
1004 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RECVTOS)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1013 bool Socket::SetIpRecvTTL(bool x
)
1015 int optval
= x
? 1 : 0;
1016 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_RECVTTL
, (char *)&optval
, sizeof(optval
)) == -1)
1018 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RECVTTL)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1027 bool Socket::SetIpRecvopts(bool x
)
1029 int optval
= x
? 1 : 0;
1030 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_RECVOPTS
, (char *)&optval
, sizeof(optval
)) == -1)
1032 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RECVOPTS)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1041 bool Socket::SetIpRetopts(bool x
)
1043 int optval
= x
? 1 : 0;
1044 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_RETOPTS
, (char *)&optval
, sizeof(optval
)) == -1)
1046 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RETOPTS)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1054 bool Socket::SetIpTOS(unsigned char tos
)
1057 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_TOS
, (char *)&tos
, sizeof(tos
)) == -1)
1059 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_TOS)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1064 Handler().LogError(this, "ip option not available", 0, "IP_TOS", LOG_LEVEL_INFO
);
1070 unsigned char Socket::IpTOS()
1072 unsigned char tos
= 0;
1074 socklen_t len
= sizeof(tos
);
1075 if (getsockopt(GetSocket(), IPPROTO_IP
, IP_TOS
, (char *)&tos
, &len
) == -1)
1077 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_TOS)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1080 Handler().LogError(this, "ip option not available", 0, "IP_TOS", LOG_LEVEL_INFO
);
1086 bool Socket::SetIpTTL(int ttl
)
1089 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_TTL
, (char *)&ttl
, sizeof(ttl
)) == -1)
1091 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_TTL)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1096 Handler().LogError(this, "ip option not available", 0, "IP_TTL", LOG_LEVEL_INFO
);
1106 socklen_t len
= sizeof(ttl
);
1107 if (getsockopt(GetSocket(), IPPROTO_IP
, IP_TTL
, (char *)&ttl
, &len
) == -1)
1109 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_TTL)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1112 Handler().LogError(this, "ip option not available", 0, "IP_TTL", LOG_LEVEL_INFO
);
1118 bool Socket::SetIpHdrincl(bool x
)
1121 int optval
= x
? 1 : 0;
1122 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_HDRINCL
, (char *)&optval
, sizeof(optval
)) == -1)
1124 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_HDRINCL)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1129 Handler().LogError(this, "ip option not available", 0, "IP_HDRINCL", LOG_LEVEL_INFO
);
1136 bool Socket::SetIpRecverr(bool x
)
1138 int optval
= x
? 1 : 0;
1139 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_RECVERR
, (char *)&optval
, sizeof(optval
)) == -1)
1141 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RECVERR)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1149 #ifdef IP_MTU_DISCOVER
1150 bool Socket::SetIpMtudiscover(bool x
)
1152 int optval
= x
? 1 : 0;
1153 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_MTU_DISCOVER
, (char *)&optval
, sizeof(optval
)) == -1)
1155 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_MTU_DISCOVER)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1167 socklen_t len
= sizeof(mtu
);
1168 if (getsockopt(GetSocket(), IPPROTO_IP
, IP_MTU
, (char *)&mtu
, &len
) == -1)
1170 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_MTU)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1177 #ifdef IP_ROUTER_ALERT
1178 bool Socket::SetIpRouterAlert(bool x
)
1180 int optval
= x
? 1 : 0;
1181 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_ROUTER_ALERT
, (char *)&optval
, sizeof(optval
)) == -1)
1183 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_ROUTER_ALERT)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1191 bool Socket::SetIpMulticastTTL(int ttl
)
1193 #ifdef IP_MULTICAST_TTL
1194 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_MULTICAST_TTL
, (char *)&ttl
, sizeof(ttl
)) == -1)
1196 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_MULTICAST_TTL)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1201 Handler().LogError(this, "ip option not available", 0, "IP_MULTICAST_TTL", LOG_LEVEL_INFO
);
1207 int Socket::IpMulticastTTL()
1210 #ifdef IP_MULTICAST_TTL
1211 socklen_t len
= sizeof(ttl
);
1212 if (getsockopt(GetSocket(), IPPROTO_IP
, IP_MULTICAST_TTL
, (char *)&ttl
, &len
) == -1)
1214 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_MULTICAST_TTL)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1217 Handler().LogError(this, "ip option not available", 0, "IP_MULTICAST_TTL", LOG_LEVEL_INFO
);
1223 bool Socket::SetMulticastLoop(bool x
)
1225 #ifdef IP_MULTICAST_LOOP
1226 int optval
= x
? 1 : 0;
1227 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_MULTICAST_LOOP
, (char *)&optval
, sizeof(optval
)) == -1)
1229 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_MULTICAST_LOOP)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1234 Handler().LogError(this, "ip option not available", 0, "IP_MULTICAST_LOOP", LOG_LEVEL_INFO
);
1241 bool Socket::IpAddMembership(struct ip_mreqn
& ref
)
1243 #ifdef IP_ADD_MEMBERSHIP
1244 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_ADD_MEMBERSHIP
, (char *)&ref
, sizeof(struct ip_mreqn
)) == -1)
1246 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1251 Handler().LogError(this, "ip option not available", 0, "IP_ADD_MEMBERSHIP", LOG_LEVEL_INFO
);
1258 bool Socket::IpAddMembership(struct ip_mreq
& ref
)
1260 #ifdef IP_ADD_MEMBERSHIP
1261 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_ADD_MEMBERSHIP
, (char *)&ref
, sizeof(struct ip_mreq
)) == -1)
1263 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1268 Handler().LogError(this, "ip option not available", 0, "IP_ADD_MEMBERSHIP", LOG_LEVEL_INFO
);
1275 bool Socket::IpDropMembership(struct ip_mreqn
& ref
)
1277 #ifdef IP_DROP_MEMBERSHIP
1278 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_DROP_MEMBERSHIP
, (char *)&ref
, sizeof(struct ip_mreqn
)) == -1)
1280 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_DROP_MEMBERSHIP)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1285 Handler().LogError(this, "ip option not available", 0, "IP_DROP_MEMBERSHIP", LOG_LEVEL_INFO
);
1292 bool Socket::IpDropMembership(struct ip_mreq
& ref
)
1294 #ifdef IP_DROP_MEMBERSHIP
1295 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_DROP_MEMBERSHIP
, (char *)&ref
, sizeof(struct ip_mreq
)) == -1)
1297 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_DROP_MEMBERSHIP)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1302 Handler().LogError(this, "ip option not available", 0, "IP_DROP_MEMBERSHIP", LOG_LEVEL_INFO
);
1308 /* SOCKET options */
1311 bool Socket::SetSoReuseaddr(bool x
)
1314 int optval
= x
? 1 : 0;
1315 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_REUSEADDR
, (char *)&optval
, sizeof(optval
)) == -1)
1317 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_REUSEADDR)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1322 Handler().LogError(this, "socket option not available", 0, "SO_REUSEADDR", LOG_LEVEL_INFO
);
1328 bool Socket::SetSoKeepalive(bool x
)
1331 int optval
= x
? 1 : 0;
1332 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_KEEPALIVE
, (char *)&optval
, sizeof(optval
)) == -1)
1334 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_KEEPALIVE)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1339 Handler().LogError(this, "socket option not available", 0, "SO_KEEPALIVE", LOG_LEVEL_INFO
);
1346 bool Socket::SetSoNosigpipe(bool x
)
1348 int optval
= x
? 1 : 0;
1349 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_NOSIGPIPE
, (char *)&optval
, sizeof(optval
)) == -1)
1351 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_NOSIGPIPE)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1359 bool Socket::SoAcceptconn()
1362 #ifdef SO_ACCEPTCONN
1363 socklen_t len
= sizeof(value
);
1364 if (getsockopt(GetSocket(), SOL_SOCKET
, SO_ACCEPTCONN
, (char *)&value
, &len
) == -1)
1366 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_ACCEPTCONN)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1369 Handler().LogError(this, "socket option not available", 0, "SO_ACCEPTCONN", LOG_LEVEL_INFO
);
1371 return value
? true : false;
1376 bool Socket::SetSoBsdcompat(bool x
)
1378 int optval
= x
? 1 : 0;
1379 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_BSDCOMPAT
, (char *)&optval
, sizeof(optval
)) == -1)
1381 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_BSDCOMPAT)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1389 #ifdef SO_BINDTODEVICE
1390 bool Socket::SetSoBindtodevice(const std::string
& intf
)
1392 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_BINDTODEVICE
, (char *)intf
.c_str(), intf
.size()) == -1)
1394 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_BINDTODEVICE)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1402 bool Socket::SetSoBroadcast(bool x
)
1405 int optval
= x
? 1 : 0;
1406 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_BROADCAST
, (char *)&optval
, sizeof(optval
)) == -1)
1408 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_BROADCAST)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1413 Handler().LogError(this, "socket option not available", 0, "SO_BROADCAST", LOG_LEVEL_INFO
);
1419 bool Socket::SetSoDebug(bool x
)
1422 int optval
= x
? 1 : 0;
1423 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_DEBUG
, (char *)&optval
, sizeof(optval
)) == -1)
1425 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_DEBUG)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1430 Handler().LogError(this, "socket option not available", 0, "SO_DEBUG", LOG_LEVEL_INFO
);
1436 int Socket::SoError()
1440 socklen_t len
= sizeof(value
);
1441 if (getsockopt(GetSocket(), SOL_SOCKET
, SO_ERROR
, (char *)&value
, &len
) == -1)
1443 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_ERROR)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1446 Handler().LogError(this, "socket option not available", 0, "SO_ERROR", LOG_LEVEL_INFO
);
1448 return value
? true : false;
1452 bool Socket::SetSoDontroute(bool x
)
1455 int optval
= x
? 1 : 0;
1456 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_DONTROUTE
, (char *)&optval
, sizeof(optval
)) == -1)
1458 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_DONTROUTE)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1463 Handler().LogError(this, "socket option not available", 0, "SO_DONTROUTE", LOG_LEVEL_INFO
);
1469 bool Socket::SetSoLinger(int onoff
, int linger
)
1473 stl
.l_onoff
= onoff
;
1474 stl
.l_linger
= linger
;
1475 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_LINGER
, (char *)&stl
, sizeof(stl
)) == -1)
1477 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_LINGER)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1482 Handler().LogError(this, "socket option not available", 0, "SO_LINGER", LOG_LEVEL_INFO
);
1488 bool Socket::SetSoOobinline(bool x
)
1491 int optval
= x
? 1 : 0;
1492 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_OOBINLINE
, (char *)&optval
, sizeof(optval
)) == -1)
1494 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_OOBINLINE)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1499 Handler().LogError(this, "socket option not available", 0, "SO_OOBINLINE", LOG_LEVEL_INFO
);
1506 bool Socket::SetSoPasscred(bool x
)
1508 int optval
= x
? 1 : 0;
1509 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_PASSCRED
, (char *)&optval
, sizeof(optval
)) == -1)
1511 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_PASSCRED)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1520 bool Socket::SoPeercred(struct ucred
& ucr
)
1522 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_PEERCRED
, (char *)&ucr
, sizeof(ucr
)) == -1)
1524 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_PEERCRED)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1533 bool Socket::SetSoPriority(int x
)
1535 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_PRIORITY
, (char *)&x
, sizeof(x
)) == -1)
1537 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_PRIORITY)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1545 bool Socket::SetSoRcvlowat(int x
)
1548 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_RCVLOWAT
, (char *)&x
, sizeof(x
)) == -1)
1550 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_RCVLOWAT)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1555 Handler().LogError(this, "socket option not available", 0, "SO_RCVLOWAT", LOG_LEVEL_INFO
);
1561 bool Socket::SetSoSndlowat(int x
)
1564 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_SNDLOWAT
, (char *)&x
, sizeof(x
)) == -1)
1566 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_SNDLOWAT)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1571 Handler().LogError(this, "socket option not available", 0, "SO_SNDLOWAT", LOG_LEVEL_INFO
);
1577 bool Socket::SetSoRcvtimeo(struct timeval
& tv
)
1580 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_RCVTIMEO
, (char *)&tv
, sizeof(tv
)) == -1)
1582 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_RCVTIMEO)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1587 Handler().LogError(this, "socket option not available", 0, "SO_RCVTIMEO", LOG_LEVEL_INFO
);
1593 bool Socket::SetSoSndtimeo(struct timeval
& tv
)
1596 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_SNDTIMEO
, (char *)&tv
, sizeof(tv
)) == -1)
1598 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_SNDTIMEO)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1603 Handler().LogError(this, "socket option not available", 0, "SO_SNDTIMEO", LOG_LEVEL_INFO
);
1609 bool Socket::SetSoRcvbuf(int x
)
1612 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_RCVBUF
, (char *)&x
, sizeof(x
)) == -1)
1614 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_RCVBUF)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1619 Handler().LogError(this, "socket option not available", 0, "SO_RCVBUF", LOG_LEVEL_INFO
);
1625 int Socket::SoRcvbuf()
1629 socklen_t len
= sizeof(value
);
1630 if (getsockopt(GetSocket(), SOL_SOCKET
, SO_RCVBUF
, (char *)&value
, &len
) == -1)
1632 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_RCVBUF)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1635 Handler().LogError(this, "socket option not available", 0, "SO_RCVBUF", LOG_LEVEL_INFO
);
1637 return value
? true : false;
1641 #ifdef SO_RCVBUFFORCE
1642 bool Socket::SetSoRcvbufforce(int x
)
1644 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_RCVBUFFORCE
, (char *)&x
, sizeof(x
)) == -1)
1646 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_RCVBUFFORCE)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1654 bool Socket::SetSoSndbuf(int x
)
1657 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_SNDBUF
, (char *)&x
, sizeof(x
)) == -1)
1659 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_SNDBUF)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1664 Handler().LogError(this, "socket option not available", 0, "SO_SNDBUF", LOG_LEVEL_INFO
);
1670 int Socket::SoSndbuf()
1674 socklen_t len
= sizeof(value
);
1675 if (getsockopt(GetSocket(), SOL_SOCKET
, SO_SNDBUF
, (char *)&value
, &len
) == -1)
1677 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_SNDBUF)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1680 Handler().LogError(this, "socket option not available", 0, "SO_SNDBUF", LOG_LEVEL_INFO
);
1682 return value
? true : false;
1686 #ifdef SO_SNDBUFFORCE
1687 bool Socket::SetSoSndbufforce(int x
)
1689 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_SNDBUFFORCE
, (char *)&x
, sizeof(x
)) == -1)
1691 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_SNDBUFFORCE)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1700 bool Socket::SetSoTimestamp(bool x
)
1702 int optval
= x
? 1 : 0;
1703 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_TIMESTAMP
, (char *)&optval
, sizeof(optval
)) == -1)
1705 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_TIMESTAMP)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1713 int Socket::SoType()
1717 socklen_t len
= sizeof(value
);
1718 if (getsockopt(GetSocket(), SOL_SOCKET
, SO_TYPE
, (char *)&value
, &len
) == -1)
1720 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_TYPE)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1723 Handler().LogError(this, "socket option not available", 0, "SO_TYPE", LOG_LEVEL_INFO
);
1725 return value
? true : false;
1729 #ifdef ENABLE_TRIGGERS
1730 void Socket::Subscribe(int id
)
1732 Handler().Subscribe(id
, this);
1736 void Socket::Unsubscribe(int id
)
1738 Handler().Unsubscribe(id
, this);
1742 void Socket::OnTrigger(int, const TriggerData
&)
1747 void Socket::OnCancelled(int)
1753 void Socket::SetTimeout(time_t secs
)
1757 Handler().AddList(m_socket
, LIST_TIMEOUT
, false);
1760 Handler().AddList(m_socket
, LIST_TIMEOUT
, true);
1761 m_timeout_start
= time(NULL
);
1762 m_timeout_limit
= secs
;
1766 void Socket::OnTimeout()
1771 void Socket::OnConnectTimeout()
1776 bool Socket::Timeout(time_t tnow
)
1778 if (tnow
- m_timeout_start
> m_timeout_limit
)
1784 #ifdef SOCKETS_NAMESPACE