root/trunk/dep/src/sockets/Socket.cpp @ 2

Revision 2, 36.3 kB (checked in by yumileroy, 17 years ago)

[svn] * Proper SVN structure

Original author: Neo2003
Date: 2008-10-02 16:23:55-05:00

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