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"
48 #ifdef ENABLE_EXCEPTIONS
49 #include "Exception.h"
51 #include "Ipv4Address.h"
54 //#define DEB(x) x; fflush(stderr);
59 #ifdef SOCKETS_NAMESPACE
60 namespace SOCKETS_NAMESPACE
{
66 WSAInitializer
Socket::m_winsock_init
;
70 Socket::Socket(ISocketHandler
& h
)
73 ,m_socket( INVALID_SOCKET
)
76 ,m_tCreate(time(NULL
))
78 ,m_b_disable_read(false)
80 ,m_b_erased_by_handler(false)
82 ,m_client_remote_address(NULL
)
83 ,m_remote_address(NULL
)
84 ,m_traffic_monitor(NULL
)
87 ,m_b_enable_ssl(false)
89 ,m_b_ssl_server(false)
101 ,m_socks4_host(h
.GetSocks4Host())
102 ,m_socks4_port(h
.GetSocks4Port())
103 ,m_socks4_userid(h
.GetSocks4Userid())
109 ,m_slave_handler(NULL
)
117 Handler().Remove(this);
118 if (m_socket
!= INVALID_SOCKET
134 void Socket::OnRead()
139 void Socket::OnWrite()
144 void Socket::OnException()
146 // %! exception doesn't always mean something bad happened, this code should be reworked
149 Handler().LogError(this, "exception on select", err
, StrError(err
), LOG_LEVEL_FATAL
);
154 void Socket::OnDelete()
159 void Socket::OnConnect()
164 void Socket::OnAccept()
171 if (m_socket
== INVALID_SOCKET
) // this could happen
173 Handler().LogError(this, "Socket::Close", 0, "file descriptor invalid", LOG_LEVEL_WARNING
);
177 if ((n
= closesocket(m_socket
)) == -1)
180 Handler().LogError(this, "close", Errno
, StrError(Errno
), LOG_LEVEL_ERROR
);
182 Handler().Set(m_socket
, false, false, false); // remove from fd_set's
183 Handler().AddList(m_socket
, LIST_CALLONCONNECT
, false);
185 Handler().AddList(m_socket
, LIST_DETACH
, false);
187 Handler().AddList(m_socket
, LIST_TIMEOUT
, false);
188 Handler().AddList(m_socket
, LIST_RETRY
, false);
189 Handler().AddList(m_socket
, LIST_CLOSE
, false);
190 m_socket
= INVALID_SOCKET
;
195 SOCKET
Socket::CreateSocket(int af
,int type
, const std::string
& protocol
)
197 struct protoent
*p
= NULL
;
201 m_socket_type
= type
;
202 m_socket_protocol
= protocol
;
204 if (!protocol
.empty())
206 p
= getprotobyname( protocol
.c_str() );
209 Handler().LogError(this, "getprotobyname", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
211 #ifdef ENABLE_EXCEPTIONS
212 throw Exception(std::string("getprotobyname() failed: ") + StrError(Errno
));
214 return INVALID_SOCKET
;
217 int protno
= p
? p
-> p_proto
: 0;
219 s
= socket(af
, type
, protno
);
220 if (s
== INVALID_SOCKET
)
222 Handler().LogError(this, "socket", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
224 #ifdef ENABLE_EXCEPTIONS
225 throw Exception(std::string("socket() failed: ") + StrError(Errno
));
227 return INVALID_SOCKET
;
230 OnOptions(af
, type
, protno
, s
);
231 Attach(INVALID_SOCKET
);
236 void Socket::Attach(SOCKET s
)
242 SOCKET
Socket::GetSocket()
248 void Socket::SetDeleteByHandler(bool x
)
254 bool Socket::DeleteByHandler()
260 void Socket::SetCloseAndDelete(bool x
)
264 Handler().AddList(m_socket
, LIST_CLOSE
, x
);
268 m_tClose
= time(NULL
);
274 bool Socket::CloseAndDelete()
280 void Socket::SetRemoteAddress(SocketAddress
& ad
) //struct sockaddr* sa, socklen_t l)
282 m_remote_address
= ad
.GetCopy();
286 std::auto_ptr
<SocketAddress
> Socket::GetRemoteSocketAddress()
288 return m_remote_address
-> GetCopy();
292 ISocketHandler
& Socket::Handler() const
296 return *m_slave_handler
;
302 ISocketHandler
& Socket::MasterHandler() const
308 ipaddr_t
Socket::GetRemoteIP4()
314 Handler().LogError(this, "GetRemoteIP4", 0, "get ipv4 address for ipv6 socket", LOG_LEVEL_WARNING
);
317 if (m_remote_address
.get() != NULL
)
319 struct sockaddr
*p
= *m_remote_address
;
320 struct sockaddr_in
*sa
= (struct sockaddr_in
*)p
;
321 memcpy(&l
, &sa
-> sin_addr
, sizeof(struct in_addr
));
329 struct in6_addr
Socket::GetRemoteIP6()
333 Handler().LogError(this, "GetRemoteIP6", 0, "get ipv6 address for ipv4 socket", LOG_LEVEL_WARNING
);
335 struct sockaddr_in6 fail
;
336 if (m_remote_address
.get() != NULL
)
338 struct sockaddr
*p
= *m_remote_address
;
339 memcpy(&fail
, p
, sizeof(struct sockaddr_in6
));
343 memset(&fail
, 0, sizeof(struct sockaddr_in6
));
345 return fail
.sin6_addr
;
351 port_t
Socket::GetRemotePort()
353 if (!m_remote_address
.get())
357 return m_remote_address
-> GetPort();
361 std::string
Socket::GetRemoteAddress()
363 if (!m_remote_address
.get())
367 return m_remote_address
-> Convert(false);
371 std::string
Socket::GetRemoteHostname()
373 if (!m_remote_address
.get())
377 return m_remote_address
-> Reverse();
381 bool Socket::SetNonblocking(bool bNb
)
384 unsigned long l
= bNb
? 1 : 0;
385 int n
= ioctlsocket(m_socket
, FIONBIO
, &l
);
388 Handler().LogError(this, "ioctlsocket(FIONBIO)", Errno
, "");
395 if (fcntl(m_socket
, F_SETFL
, O_NONBLOCK
) == -1)
397 Handler().LogError(this, "fcntl(F_SETFL, O_NONBLOCK)", Errno
, StrError(Errno
), LOG_LEVEL_ERROR
);
403 if (fcntl(m_socket
, F_SETFL
, 0) == -1)
405 Handler().LogError(this, "fcntl(F_SETFL, 0)", Errno
, StrError(Errno
), LOG_LEVEL_ERROR
);
414 bool Socket::SetNonblocking(bool bNb
, SOCKET s
)
417 unsigned long l
= bNb
? 1 : 0;
418 int n
= ioctlsocket(s
, FIONBIO
, &l
);
421 Handler().LogError(this, "ioctlsocket(FIONBIO)", Errno
, "");
428 if (fcntl(s
, F_SETFL
, O_NONBLOCK
) == -1)
430 Handler().LogError(this, "fcntl(F_SETFL, O_NONBLOCK)", Errno
, StrError(Errno
), LOG_LEVEL_ERROR
);
436 if (fcntl(s
, F_SETFL
, 0) == -1)
438 Handler().LogError(this, "fcntl(F_SETFL, 0)", Errno
, StrError(Errno
), LOG_LEVEL_ERROR
);
447 void Socket::Set(bool bRead
, bool bWrite
, bool bException
)
449 Handler().Set(m_socket
, bRead
, bWrite
, bException
);
455 if (m_socket
!= INVALID_SOCKET
&& !CloseAndDelete())
461 void Socket::OnLine(const std::string
& )
466 void Socket::OnConnectFailed()
471 Socket
*Socket::GetParent()
477 void Socket::SetParent(Socket
*x
)
483 port_t
Socket::GetPort()
485 Handler().LogError(this, "GetPort", 0, "GetPort only implemented for ListenSocket", LOG_LEVEL_WARNING
);
490 bool Socket::OnConnectRetry()
496 #ifdef ENABLE_RECONNECT
497 void Socket::OnReconnect()
503 time_t Socket::Uptime()
505 return time(NULL
) - m_tCreate
;
510 void Socket::SetIpv6(bool x
)
516 bool Socket::IsIpv6()
523 void Socket::DisableRead(bool x
)
525 m_b_disable_read
= x
;
529 bool Socket::IsDisableRead()
531 return m_b_disable_read
;
535 void Socket::SendBuf(const char *,size_t,int)
540 void Socket::Send(const std::string
&,int)
545 void Socket::SetConnected(bool x
)
551 bool Socket::IsConnected()
557 void Socket::OnDisconnect()
562 void Socket::SetLost()
574 void Socket::SetErasedByHandler(bool x
)
576 m_b_erased_by_handler
= x
;
580 bool Socket::ErasedByHandler()
582 return m_b_erased_by_handler
;
586 time_t Socket::TimeSinceClose()
588 return time(NULL
) - m_tClose
;
592 void Socket::SetClientRemoteAddress(SocketAddress
& ad
)
596 Handler().LogError(this, "SetClientRemoteAddress", 0, "remote address not valid", LOG_LEVEL_ERROR
);
598 m_client_remote_address
= ad
.GetCopy();
602 std::auto_ptr
<SocketAddress
> Socket::GetClientRemoteAddress()
604 if (!m_client_remote_address
.get())
606 Handler().LogError(this, "GetClientRemoteAddress", 0, "remote address not yet set", LOG_LEVEL_ERROR
);
608 return m_client_remote_address
-> GetCopy();
612 uint64_t Socket::GetBytesSent(bool)
618 uint64_t Socket::GetBytesReceived(bool)
625 void Socket::OnSSLConnect()
630 void Socket::OnSSLAccept()
635 bool Socket::SSLNegotiate()
643 return m_b_enable_ssl
;
647 void Socket::EnableSSL(bool x
)
653 bool Socket::IsSSLNegotiate()
659 void Socket::SetSSLNegotiate(bool x
)
665 bool Socket::IsSSLServer()
667 return m_b_ssl_server
;
671 void Socket::SetSSLServer(bool x
)
677 void Socket::OnSSLConnectFailed()
682 void Socket::OnSSLAcceptFailed()
685 #endif // HAVE_OPENSSL
689 void Socket::CopyConnection(Socket
*sock
)
691 Attach( sock
-> GetSocket() );
693 SetIpv6( sock
-> IsIpv6() );
695 SetSocketType( sock
-> GetSocketType() );
696 SetSocketProtocol( sock
-> GetSocketProtocol() );
698 SetClientRemoteAddress( *sock
-> GetClientRemoteAddress() );
699 SetRemoteAddress( *sock
-> GetRemoteSocketAddress() );
703 void Socket::SetIsClient()
709 void Socket::SetSocketType(int x
)
715 int Socket::GetSocketType()
717 return m_socket_type
;
721 void Socket::SetSocketProtocol(const std::string
& x
)
723 m_socket_protocol
= x
;
727 const std::string
& Socket::GetSocketProtocol()
729 return m_socket_protocol
;
733 void Socket::SetRetain()
735 if (m_bClient
) m_bRetain
= true;
739 bool Socket::Retain()
745 #endif // ENABLE_POOL
749 void Socket::OnSocks4Connect()
751 Handler().LogError(this, "OnSocks4Connect", 0, "Use with TcpSocket only");
755 void Socket::OnSocks4ConnectFailed()
757 Handler().LogError(this, "OnSocks4ConnectFailed", 0, "Use with TcpSocket only");
761 bool Socket::OnSocks4Read()
763 Handler().LogError(this, "OnSocks4Read", 0, "Use with TcpSocket only");
768 void Socket::SetSocks4Host(const std::string
& host
)
770 Utility::u2ip(host
, m_socks4_host
);
774 bool Socket::Socks4()
780 void Socket::SetSocks4(bool x
)
786 void Socket::SetSocks4Host(ipaddr_t a
)
792 void Socket::SetSocks4Port(port_t p
)
798 void Socket::SetSocks4Userid(const std::string
& x
)
804 ipaddr_t
Socket::GetSocks4Host()
806 return m_socks4_host
;
810 port_t
Socket::GetSocks4Port()
812 return m_socks4_port
;
816 const std::string
& Socket::GetSocks4Userid()
818 return m_socks4_userid
;
820 #endif // ENABLE_SOCKS4
824 bool Socket::Detach()
826 if (!DeleteByHandler())
837 void Socket::DetachSocket()
840 m_pThread
= new SocketThread(this);
841 m_pThread
-> SetRelease(true);
845 void Socket::OnDetached()
850 void Socket::SetDetach(bool x
)
852 Handler().AddList(m_socket
, LIST_DETACH
, x
);
857 bool Socket::IsDetach()
863 void Socket::SetDetached(bool x
)
869 const bool Socket::IsDetached() const
875 void Socket::SetSlaveHandler(ISocketHandler
*p
)
881 Socket::SocketThread::SocketThread(Socket
*p
)
885 // Creator will release
889 Socket::SocketThread::~SocketThread()
904 void Socket::SocketThread::Run()
909 m_socket
-> SetSlaveHandler(&h
);
910 m_socket
-> OnDetached();
911 while (h
.GetCount() && IsRunning())
915 // m_socket now deleted oops
916 // yeah oops m_socket delete its socket thread, that means this
917 // so Socket will no longer delete its socket thread, instead we do this:
920 #endif // ENABLE_DETACH
923 #ifdef ENABLE_RESOLVER
924 int Socket::Resolve(const std::string
& host
,port_t port
)
926 return Handler().Resolve(this, host
, port
);
931 int Socket::Resolve6(const std::string
& host
,port_t port
)
933 return Handler().Resolve6(this, host
, port
);
938 int Socket::Resolve(ipaddr_t a
)
940 return Handler().Resolve(this, a
);
945 int Socket::Resolve(in6_addr
& a
)
947 return Handler().Resolve(this, a
);
952 void Socket::OnResolved(int,ipaddr_t
,port_t
)
958 void Socket::OnResolved(int,in6_addr
&,port_t
)
964 void Socket::OnReverseResolved(int,const std::string
&)
969 void Socket::OnResolveFailed(int)
972 #endif // ENABLE_RESOLVER
978 bool Socket::SetIpOptions(const void *p
, socklen_t len
)
981 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_OPTIONS
, (char *)p
, len
) == -1)
983 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_OPTIONS)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
988 Handler().LogError(this, "ip option not available", 0, "IP_OPTIONS", LOG_LEVEL_INFO
);
995 bool Socket::SetIpPktinfo(bool x
)
997 int optval
= x
? 1 : 0;
998 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_PKTINFO
, (char *)&optval
, sizeof(optval
)) == -1)
1000 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_PKTINFO)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1009 bool Socket::SetIpRecvTOS(bool x
)
1011 int optval
= x
? 1 : 0;
1012 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_RECVTOS
, (char *)&optval
, sizeof(optval
)) == -1)
1014 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RECVTOS)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1023 bool Socket::SetIpRecvTTL(bool x
)
1025 int optval
= x
? 1 : 0;
1026 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_RECVTTL
, (char *)&optval
, sizeof(optval
)) == -1)
1028 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RECVTTL)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1037 bool Socket::SetIpRecvopts(bool x
)
1039 int optval
= x
? 1 : 0;
1040 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_RECVOPTS
, (char *)&optval
, sizeof(optval
)) == -1)
1042 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RECVOPTS)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1051 bool Socket::SetIpRetopts(bool x
)
1053 int optval
= x
? 1 : 0;
1054 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_RETOPTS
, (char *)&optval
, sizeof(optval
)) == -1)
1056 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RETOPTS)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1064 bool Socket::SetIpTOS(unsigned char tos
)
1067 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_TOS
, (char *)&tos
, sizeof(tos
)) == -1)
1069 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_TOS)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1074 Handler().LogError(this, "ip option not available", 0, "IP_TOS", LOG_LEVEL_INFO
);
1080 unsigned char Socket::IpTOS()
1082 unsigned char tos
= 0;
1084 socklen_t len
= sizeof(tos
);
1085 if (getsockopt(GetSocket(), IPPROTO_IP
, IP_TOS
, (char *)&tos
, &len
) == -1)
1087 Handler().LogError(this, "getsockopt(IPPROTO_IP, IP_TOS)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1090 Handler().LogError(this, "ip option not available", 0, "IP_TOS", LOG_LEVEL_INFO
);
1096 bool Socket::SetIpTTL(int ttl
)
1099 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_TTL
, (char *)&ttl
, sizeof(ttl
)) == -1)
1101 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_TTL)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1106 Handler().LogError(this, "ip option not available", 0, "IP_TTL", LOG_LEVEL_INFO
);
1116 socklen_t len
= sizeof(ttl
);
1117 if (getsockopt(GetSocket(), IPPROTO_IP
, IP_TTL
, (char *)&ttl
, &len
) == -1)
1119 Handler().LogError(this, "getsockopt(IPPROTO_IP, IP_TTL)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1122 Handler().LogError(this, "ip option not available", 0, "IP_TTL", LOG_LEVEL_INFO
);
1128 bool Socket::SetIpHdrincl(bool x
)
1131 int optval
= x
? 1 : 0;
1132 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_HDRINCL
, (char *)&optval
, sizeof(optval
)) == -1)
1134 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_HDRINCL)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1139 Handler().LogError(this, "ip option not available", 0, "IP_HDRINCL", LOG_LEVEL_INFO
);
1146 bool Socket::SetIpRecverr(bool x
)
1148 int optval
= x
? 1 : 0;
1149 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_RECVERR
, (char *)&optval
, sizeof(optval
)) == -1)
1151 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RECVERR)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1159 #ifdef IP_MTU_DISCOVER
1160 bool Socket::SetIpMtudiscover(bool x
)
1162 int optval
= x
? 1 : 0;
1163 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_MTU_DISCOVER
, (char *)&optval
, sizeof(optval
)) == -1)
1165 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_MTU_DISCOVER)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1177 socklen_t len
= sizeof(mtu
);
1178 if (getsockopt(GetSocket(), IPPROTO_IP
, IP_MTU
, (char *)&mtu
, &len
) == -1)
1180 Handler().LogError(this, "getsockopt(IPPROTO_IP, IP_MTU)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1187 #ifdef IP_ROUTER_ALERT
1188 bool Socket::SetIpRouterAlert(bool x
)
1190 int optval
= x
? 1 : 0;
1191 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_ROUTER_ALERT
, (char *)&optval
, sizeof(optval
)) == -1)
1193 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_ROUTER_ALERT)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1201 bool Socket::SetIpMulticastTTL(int ttl
)
1203 #ifdef IP_MULTICAST_TTL
1204 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_MULTICAST_TTL
, (char *)&ttl
, sizeof(ttl
)) == -1)
1206 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_MULTICAST_TTL)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1211 Handler().LogError(this, "ip option not available", 0, "IP_MULTICAST_TTL", LOG_LEVEL_INFO
);
1217 int Socket::IpMulticastTTL()
1220 #ifdef IP_MULTICAST_TTL
1221 socklen_t len
= sizeof(ttl
);
1222 if (getsockopt(GetSocket(), IPPROTO_IP
, IP_MULTICAST_TTL
, (char *)&ttl
, &len
) == -1)
1224 Handler().LogError(this, "getsockopt(IPPROTO_IP, IP_MULTICAST_TTL)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1227 Handler().LogError(this, "ip option not available", 0, "IP_MULTICAST_TTL", LOG_LEVEL_INFO
);
1233 bool Socket::SetMulticastLoop(bool x
)
1235 #ifdef IP_MULTICAST_LOOP
1236 int optval
= x
? 1 : 0;
1237 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_MULTICAST_LOOP
, (char *)&optval
, sizeof(optval
)) == -1)
1239 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_MULTICAST_LOOP)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1244 Handler().LogError(this, "ip option not available", 0, "IP_MULTICAST_LOOP", LOG_LEVEL_INFO
);
1251 bool Socket::IpAddMembership(struct ip_mreqn
& ref
)
1253 #ifdef IP_ADD_MEMBERSHIP
1254 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_ADD_MEMBERSHIP
, (char *)&ref
, sizeof(struct ip_mreqn
)) == -1)
1256 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1261 Handler().LogError(this, "ip option not available", 0, "IP_ADD_MEMBERSHIP", LOG_LEVEL_INFO
);
1268 bool Socket::IpAddMembership(struct ip_mreq
& ref
)
1270 #ifdef IP_ADD_MEMBERSHIP
1271 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_ADD_MEMBERSHIP
, (char *)&ref
, sizeof(struct ip_mreq
)) == -1)
1273 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1278 Handler().LogError(this, "ip option not available", 0, "IP_ADD_MEMBERSHIP", LOG_LEVEL_INFO
);
1285 bool Socket::IpDropMembership(struct ip_mreqn
& ref
)
1287 #ifdef IP_DROP_MEMBERSHIP
1288 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_DROP_MEMBERSHIP
, (char *)&ref
, sizeof(struct ip_mreqn
)) == -1)
1290 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_DROP_MEMBERSHIP)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1295 Handler().LogError(this, "ip option not available", 0, "IP_DROP_MEMBERSHIP", LOG_LEVEL_INFO
);
1302 bool Socket::IpDropMembership(struct ip_mreq
& ref
)
1304 #ifdef IP_DROP_MEMBERSHIP
1305 if (setsockopt(GetSocket(), IPPROTO_IP
, IP_DROP_MEMBERSHIP
, (char *)&ref
, sizeof(struct ip_mreq
)) == -1)
1307 Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_DROP_MEMBERSHIP)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1312 Handler().LogError(this, "ip option not available", 0, "IP_DROP_MEMBERSHIP", LOG_LEVEL_INFO
);
1318 /* SOCKET options */
1321 bool Socket::SetSoReuseaddr(bool x
)
1324 int optval
= x
? 1 : 0;
1325 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_REUSEADDR
, (char *)&optval
, sizeof(optval
)) == -1)
1327 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_REUSEADDR)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1332 Handler().LogError(this, "socket option not available", 0, "SO_REUSEADDR", LOG_LEVEL_INFO
);
1338 bool Socket::SetSoKeepalive(bool x
)
1341 int optval
= x
? 1 : 0;
1342 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_KEEPALIVE
, (char *)&optval
, sizeof(optval
)) == -1)
1344 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_KEEPALIVE)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1349 Handler().LogError(this, "socket option not available", 0, "SO_KEEPALIVE", LOG_LEVEL_INFO
);
1356 bool Socket::SetSoNosigpipe(bool x
)
1358 int optval
= x
? 1 : 0;
1359 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_NOSIGPIPE
, (char *)&optval
, sizeof(optval
)) == -1)
1361 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_NOSIGPIPE)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1369 bool Socket::SoAcceptconn()
1372 #ifdef SO_ACCEPTCONN
1373 socklen_t len
= sizeof(value
);
1374 if (getsockopt(GetSocket(), SOL_SOCKET
, SO_ACCEPTCONN
, (char *)&value
, &len
) == -1)
1376 Handler().LogError(this, "getsockopt(SOL_SOCKET, SO_ACCEPTCONN)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1379 Handler().LogError(this, "socket option not available", 0, "SO_ACCEPTCONN", LOG_LEVEL_INFO
);
1381 return value
? true : false;
1386 bool Socket::SetSoBsdcompat(bool x
)
1388 int optval
= x
? 1 : 0;
1389 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_BSDCOMPAT
, (char *)&optval
, sizeof(optval
)) == -1)
1391 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_BSDCOMPAT)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1399 #ifdef SO_BINDTODEVICE
1400 bool Socket::SetSoBindtodevice(const std::string
& intf
)
1402 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_BINDTODEVICE
, (char *)intf
.c_str(), intf
.size()) == -1)
1404 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_BINDTODEVICE)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1412 bool Socket::SetSoBroadcast(bool x
)
1415 int optval
= x
? 1 : 0;
1416 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_BROADCAST
, (char *)&optval
, sizeof(optval
)) == -1)
1418 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_BROADCAST)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1423 Handler().LogError(this, "socket option not available", 0, "SO_BROADCAST", LOG_LEVEL_INFO
);
1429 bool Socket::SetSoDebug(bool x
)
1432 int optval
= x
? 1 : 0;
1433 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_DEBUG
, (char *)&optval
, sizeof(optval
)) == -1)
1435 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_DEBUG)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1440 Handler().LogError(this, "socket option not available", 0, "SO_DEBUG", LOG_LEVEL_INFO
);
1446 int Socket::SoError()
1450 socklen_t len
= sizeof(value
);
1451 if (getsockopt(GetSocket(), SOL_SOCKET
, SO_ERROR
, (char *)&value
, &len
) == -1)
1453 Handler().LogError(this, "getsockopt(SOL_SOCKET, SO_ERROR)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1456 Handler().LogError(this, "socket option not available", 0, "SO_ERROR", LOG_LEVEL_INFO
);
1462 bool Socket::SetSoDontroute(bool x
)
1465 int optval
= x
? 1 : 0;
1466 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_DONTROUTE
, (char *)&optval
, sizeof(optval
)) == -1)
1468 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_DONTROUTE)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1473 Handler().LogError(this, "socket option not available", 0, "SO_DONTROUTE", LOG_LEVEL_INFO
);
1479 bool Socket::SetSoLinger(int onoff
, int linger
)
1483 stl
.l_onoff
= onoff
;
1484 stl
.l_linger
= linger
;
1485 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_LINGER
, (char *)&stl
, sizeof(stl
)) == -1)
1487 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_LINGER)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1492 Handler().LogError(this, "socket option not available", 0, "SO_LINGER", LOG_LEVEL_INFO
);
1498 bool Socket::SetSoOobinline(bool x
)
1501 int optval
= x
? 1 : 0;
1502 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_OOBINLINE
, (char *)&optval
, sizeof(optval
)) == -1)
1504 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_OOBINLINE)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1509 Handler().LogError(this, "socket option not available", 0, "SO_OOBINLINE", LOG_LEVEL_INFO
);
1516 bool Socket::SetSoPasscred(bool x
)
1518 int optval
= x
? 1 : 0;
1519 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_PASSCRED
, (char *)&optval
, sizeof(optval
)) == -1)
1521 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_PASSCRED)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1530 bool Socket::SoPeercred(struct ucred
& ucr
)
1532 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_PEERCRED
, (char *)&ucr
, sizeof(ucr
)) == -1)
1534 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_PEERCRED)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1543 bool Socket::SetSoPriority(int x
)
1545 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_PRIORITY
, (char *)&x
, sizeof(x
)) == -1)
1547 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_PRIORITY)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1555 bool Socket::SetSoRcvlowat(int x
)
1558 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_RCVLOWAT
, (char *)&x
, sizeof(x
)) == -1)
1560 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_RCVLOWAT)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1565 Handler().LogError(this, "socket option not available", 0, "SO_RCVLOWAT", LOG_LEVEL_INFO
);
1571 bool Socket::SetSoSndlowat(int x
)
1574 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_SNDLOWAT
, (char *)&x
, sizeof(x
)) == -1)
1576 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_SNDLOWAT)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1581 Handler().LogError(this, "socket option not available", 0, "SO_SNDLOWAT", LOG_LEVEL_INFO
);
1587 bool Socket::SetSoRcvtimeo(struct timeval
& tv
)
1590 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_RCVTIMEO
, (char *)&tv
, sizeof(tv
)) == -1)
1592 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_RCVTIMEO)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1597 Handler().LogError(this, "socket option not available", 0, "SO_RCVTIMEO", LOG_LEVEL_INFO
);
1603 bool Socket::SetSoSndtimeo(struct timeval
& tv
)
1606 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_SNDTIMEO
, (char *)&tv
, sizeof(tv
)) == -1)
1608 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_SNDTIMEO)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1613 Handler().LogError(this, "socket option not available", 0, "SO_SNDTIMEO", LOG_LEVEL_INFO
);
1619 bool Socket::SetSoRcvbuf(int x
)
1622 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_RCVBUF
, (char *)&x
, sizeof(x
)) == -1)
1624 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_RCVBUF)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1629 Handler().LogError(this, "socket option not available", 0, "SO_RCVBUF", LOG_LEVEL_INFO
);
1635 int Socket::SoRcvbuf()
1639 socklen_t len
= sizeof(value
);
1640 if (getsockopt(GetSocket(), SOL_SOCKET
, SO_RCVBUF
, (char *)&value
, &len
) == -1)
1642 Handler().LogError(this, "getsockopt(SOL_SOCKET, SO_RCVBUF)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1645 Handler().LogError(this, "socket option not available", 0, "SO_RCVBUF", LOG_LEVEL_INFO
);
1651 #ifdef SO_RCVBUFFORCE
1652 bool Socket::SetSoRcvbufforce(int x
)
1654 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_RCVBUFFORCE
, (char *)&x
, sizeof(x
)) == -1)
1656 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_RCVBUFFORCE)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1664 bool Socket::SetSoSndbuf(int x
)
1667 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_SNDBUF
, (char *)&x
, sizeof(x
)) == -1)
1669 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_SNDBUF)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1674 Handler().LogError(this, "socket option not available", 0, "SO_SNDBUF", LOG_LEVEL_INFO
);
1680 int Socket::SoSndbuf()
1684 socklen_t len
= sizeof(value
);
1685 if (getsockopt(GetSocket(), SOL_SOCKET
, SO_SNDBUF
, (char *)&value
, &len
) == -1)
1687 Handler().LogError(this, "getsockopt(SOL_SOCKET, SO_SNDBUF)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1690 Handler().LogError(this, "socket option not available", 0, "SO_SNDBUF", LOG_LEVEL_INFO
);
1696 #ifdef SO_SNDBUFFORCE
1697 bool Socket::SetSoSndbufforce(int x
)
1699 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_SNDBUFFORCE
, (char *)&x
, sizeof(x
)) == -1)
1701 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_SNDBUFFORCE)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1710 bool Socket::SetSoTimestamp(bool x
)
1712 int optval
= x
? 1 : 0;
1713 if (setsockopt(GetSocket(), SOL_SOCKET
, SO_TIMESTAMP
, (char *)&optval
, sizeof(optval
)) == -1)
1715 Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_TIMESTAMP)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1723 int Socket::SoType()
1727 socklen_t len
= sizeof(value
);
1728 if (getsockopt(GetSocket(), SOL_SOCKET
, SO_TYPE
, (char *)&value
, &len
) == -1)
1730 Handler().LogError(this, "getsockopt(SOL_SOCKET, SO_TYPE)", Errno
, StrError(Errno
), LOG_LEVEL_FATAL
);
1733 Handler().LogError(this, "socket option not available", 0, "SO_TYPE", LOG_LEVEL_INFO
);
1739 #ifdef ENABLE_TRIGGERS
1740 void Socket::Subscribe(int id
)
1742 Handler().Subscribe(id
, this);
1746 void Socket::Unsubscribe(int id
)
1748 Handler().Unsubscribe(id
, this);
1752 void Socket::OnTrigger(int, const TriggerData
&)
1757 void Socket::OnCancelled(int)
1763 void Socket::SetTimeout(time_t secs
)
1767 Handler().AddList(m_socket
, LIST_TIMEOUT
, false);
1770 Handler().AddList(m_socket
, LIST_TIMEOUT
, true);
1771 m_timeout_start
= time(NULL
);
1772 m_timeout_limit
= secs
;
1776 void Socket::OnTimeout()
1781 void Socket::OnConnectTimeout()
1786 bool Socket::Timeout(time_t tnow
)
1788 if (tnow
- m_timeout_start
> m_timeout_limit
)
1794 /** Returns local port number for bound socket file descriptor. */
1795 port_t
Socket::GetSockPort()
1801 struct sockaddr_in6 sa
;
1802 socklen_t sockaddr_length
= sizeof(struct sockaddr_in6
);
1803 if (getsockname(GetSocket(), (struct sockaddr
*)&sa
, (socklen_t
*)&sockaddr_length
) == -1)
1804 memset(&sa
, 0, sizeof(sa
));
1805 return ntohs(sa
.sin6_port
);
1809 struct sockaddr_in sa
;
1810 socklen_t sockaddr_length
= sizeof(struct sockaddr_in
);
1811 if (getsockname(GetSocket(), (struct sockaddr
*)&sa
, (socklen_t
*)&sockaddr_length
) == -1)
1812 memset(&sa
, 0, sizeof(sa
));
1813 return ntohs(sa
.sin_port
);
1817 /** Returns local ipv4 address for bound socket file descriptor. */
1818 ipaddr_t
Socket::GetSockIP4()
1828 struct sockaddr_in sa
;
1829 socklen_t sockaddr_length
= sizeof(struct sockaddr_in
);
1830 if (getsockname(GetSocket(), (struct sockaddr
*)&sa
, (socklen_t
*)&sockaddr_length
) == -1)
1831 memset(&sa
, 0, sizeof(sa
));
1833 memcpy(&a
, &sa
.sin_addr
, 4);
1838 /** Returns local ipv4 address as text for bound socket file descriptor. */
1839 std::string
Socket::GetSockAddress()
1849 struct sockaddr_in sa
;
1850 socklen_t sockaddr_length
= sizeof(struct sockaddr_in
);
1851 if (getsockname(GetSocket(), (struct sockaddr
*)&sa
, (socklen_t
*)&sockaddr_length
) == -1)
1852 memset(&sa
, 0, sizeof(sa
));
1853 Ipv4Address
addr( sa
);
1854 return addr
.Convert();
1860 /** Returns local ipv6 address for bound socket file descriptor. */
1861 struct in6_addr
Socket::GetSockIP6()
1865 struct sockaddr_in6 sa
;
1866 socklen_t sockaddr_length
= sizeof(struct sockaddr_in6
);
1867 if (getsockname(GetSocket(), (struct sockaddr
*)&sa
, (socklen_t
*)&sockaddr_length
) == -1)
1868 memset(&sa
, 0, sizeof(sa
));
1869 return sa
.sin6_addr
;
1872 memset(&a
, 0, sizeof(a
));
1877 /** Returns local ipv6 address as text for bound socket file descriptor. */
1878 std::string
Socket::GetSockAddress6()
1882 struct sockaddr_in6 sa
;
1883 socklen_t sockaddr_length
= sizeof(struct sockaddr_in6
);
1884 if (getsockname(GetSocket(), (struct sockaddr
*)&sa
, (socklen_t
*)&sockaddr_length
) == -1)
1885 memset(&sa
, 0, sizeof(sa
));
1886 Ipv6Address
addr( sa
);
1887 return addr
.Convert();
1895 #ifdef SOCKETS_NAMESPACE