1 /////////////////////////////////////////////////////////////////////////////
2 // Name:       src/common/socket.cpp
3 // Purpose:    Socket handler classes
4 // Authors:    Guilhem Lavaux, Guillermo Rodriguez Garcia
5 // Created:    April 1997
6 // Copyright:  (C) 1999-1997, Guilhem Lavaux
7 //             (C) 1999-2000, Guillermo Rodriguez Garcia
8 //             (C) 2008 Vadim Zeitlin
9 // Licence:    wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11 
12 // ==========================================================================
13 // Declarations
14 // ==========================================================================
15 
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18 
19 #ifdef __BORLANDC__
20     #pragma hdrstop
21 #endif
22 
23 #if wxUSE_SOCKETS
24 
25 #include "wx/socket.h"
26 
27 #ifndef WX_PRECOMP
28     #include "wx/object.h"
29     #include "wx/string.h"
30     #include "wx/intl.h"
31     #include "wx/log.h"
32     #include "wx/event.h"
33     #include "wx/app.h"
34     #include "wx/utils.h"
35     #include "wx/timer.h"
36     #include "wx/module.h"
37 #endif
38 
39 #include "wx/apptrait.h"
40 #include "wx/sckaddr.h"
41 #include "wx/stopwatch.h"
42 #include "wx/thread.h"
43 #include "wx/evtloop.h"
44 #include "wx/link.h"
45 
46 #include "wx/private/fd.h"
47 #include "wx/private/socket.h"
48 
49 #ifdef __UNIX__
50     #include <errno.h>
51 #endif
52 
53 // we use MSG_NOSIGNAL to avoid getting SIGPIPE when sending data to a remote
54 // host which closed the connection if it is available, otherwise we rely on
55 // SO_NOSIGPIPE existency
56 //
57 // this should cover all the current Unix systems (Windows never sends any
58 // signals anyhow) but if we find one that has neither we should explicitly
59 // ignore SIGPIPE for it
60 // OpenVMS has neither MSG_NOSIGNAL nor SO_NOSIGPIPE. However the socket sample
61 // seems to work. Not sure if problems will show up on OpenVMS using sockets.
62 #ifdef MSG_NOSIGNAL
63     #define wxSOCKET_MSG_NOSIGNAL MSG_NOSIGNAL
64 #else // MSG_NOSIGNAL not available (BSD including OS X)
65     // next best possibility is to use SO_NOSIGPIPE socket option, this covers
66     // BSD systems (including OS X) -- but if we don't have it neither (AIX and
67     // old HP-UX do not), we have to fall back to the old way of simply
68     // disabling SIGPIPE temporarily, so define a class to do it in a safe way
69     #if defined(__UNIX__) && !defined(SO_NOSIGPIPE)
70     extern "C" { typedef void (*wxSigHandler_t)(int); }
71     namespace
72     {
73         class IgnoreSignal
74         {
75         public:
76             // ctor disables the given signal
IgnoreSignal(int sig)77             IgnoreSignal(int sig)
78                 : m_handler(signal(sig, SIG_IGN)),
79                   m_sig(sig)
80             {
81             }
82 
83             // dtor restores the old handler
~IgnoreSignal()84             ~IgnoreSignal()
85             {
86                 signal(m_sig, m_handler);
87             }
88 
89         private:
90             const wxSigHandler_t m_handler;
91             const int m_sig;
92 
93             wxDECLARE_NO_COPY_CLASS(IgnoreSignal);
94         };
95     } // anonymous namespace
96 
97     #define wxNEEDS_IGNORE_SIGPIPE
98     #endif // Unix without SO_NOSIGPIPE
99 
100     #define wxSOCKET_MSG_NOSIGNAL 0
101 #endif
102 
103 // DLL options compatibility check:
104 #include "wx/build.h"
105 WX_CHECK_BUILD_OPTIONS("wxNet")
106 
107 // --------------------------------------------------------------------------
108 // macros and constants
109 // --------------------------------------------------------------------------
110 
111 // event
112 wxDEFINE_EVENT(wxEVT_SOCKET, wxSocketEvent);
113 
114 // discard buffer
115 #define MAX_DISCARD_SIZE (10 * 1024)
116 
117 #define wxTRACE_Socket wxT("wxSocket")
118 
119 // --------------------------------------------------------------------------
120 // wxWin macros
121 // --------------------------------------------------------------------------
122 
123 IMPLEMENT_CLASS(wxSocketBase, wxObject)
124 IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
125 IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
126 IMPLEMENT_CLASS(wxDatagramSocket, wxSocketBase)
127 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
128 
129 // ----------------------------------------------------------------------------
130 // private functions
131 // ----------------------------------------------------------------------------
132 
133 namespace
134 {
135 
SetTimeValFromMS(timeval & tv,unsigned long ms)136 void SetTimeValFromMS(timeval& tv, unsigned long ms)
137 {
138     tv.tv_sec  = (ms / 1000);
139     tv.tv_usec = (ms % 1000) * 1000;
140 }
141 
142 } // anonymous namespace
143 
144 // --------------------------------------------------------------------------
145 // private classes
146 // --------------------------------------------------------------------------
147 
148 class wxSocketState : public wxObject
149 {
150 public:
151     wxSocketFlags            m_flags;
152     wxSocketEventFlags       m_eventmask;
153     bool                     m_notify;
154     void                    *m_clientData;
155 
156 public:
wxSocketState()157     wxSocketState() : wxObject() {}
158 
159     wxDECLARE_NO_COPY_CLASS(wxSocketState);
160 };
161 
162 // wxSocketWaitModeChanger: temporarily change the socket flags affecting its
163 // wait mode
164 class wxSocketWaitModeChanger
165 {
166 public:
167     // temporarily set the flags to include the flag value which may be either
168     // wxSOCKET_NOWAIT or wxSOCKET_WAITALL
wxSocketWaitModeChanger(wxSocketBase * socket,int flag)169     wxSocketWaitModeChanger(wxSocketBase *socket, int flag)
170         : m_socket(socket),
171           m_oldflags(socket->GetFlags())
172 
173     {
174         // We can be passed only wxSOCKET_WAITALL{_READ,_WRITE} or
175         // wxSOCKET_NOWAIT{_READ,_WRITE} normally.
176         wxASSERT_MSG( !(flag & wxSOCKET_WAITALL) || !(flag & wxSOCKET_NOWAIT),
177                       "not a wait flag" );
178 
179         // preserve wxSOCKET_BLOCK value when switching to wxSOCKET_WAITALL
180         // mode but not when switching to wxSOCKET_NOWAIT as the latter is
181         // incompatible with wxSOCKET_BLOCK
182         if ( flag != wxSOCKET_NOWAIT )
183             flag |= m_oldflags & wxSOCKET_BLOCK;
184 
185         socket->SetFlags(flag);
186     }
187 
~wxSocketWaitModeChanger()188     ~wxSocketWaitModeChanger()
189     {
190         m_socket->SetFlags(m_oldflags);
191     }
192 
193 private:
194     wxSocketBase * const m_socket;
195     const int m_oldflags;
196 
197     wxDECLARE_NO_COPY_CLASS(wxSocketWaitModeChanger);
198 };
199 
200 // wxSocketRead/WriteGuard are instantiated before starting reading
201 // from/writing to the socket
202 class wxSocketReadGuard
203 {
204 public:
wxSocketReadGuard(wxSocketBase * socket)205     wxSocketReadGuard(wxSocketBase *socket)
206         : m_socket(socket)
207     {
208         wxASSERT_MSG( !m_socket->m_reading, "read reentrancy?" );
209 
210         m_socket->m_reading = true;
211     }
212 
~wxSocketReadGuard()213     ~wxSocketReadGuard()
214     {
215         m_socket->m_reading = false;
216 
217         // connection could have been lost while reading, in this case calling
218         // ReenableEvents() would assert and is not necessary anyhow
219         wxSocketImpl * const impl = m_socket->m_impl;
220         if ( impl && impl->m_fd != INVALID_SOCKET )
221             impl->ReenableEvents(wxSOCKET_INPUT_FLAG);
222     }
223 
224 private:
225     wxSocketBase * const m_socket;
226 
227     wxDECLARE_NO_COPY_CLASS(wxSocketReadGuard);
228 };
229 
230 class wxSocketWriteGuard
231 {
232 public:
wxSocketWriteGuard(wxSocketBase * socket)233     wxSocketWriteGuard(wxSocketBase *socket)
234         : m_socket(socket)
235     {
236         wxASSERT_MSG( !m_socket->m_writing, "write reentrancy?" );
237 
238         m_socket->m_writing = true;
239     }
240 
~wxSocketWriteGuard()241     ~wxSocketWriteGuard()
242     {
243         m_socket->m_writing = false;
244 
245         wxSocketImpl * const impl = m_socket->m_impl;
246         if ( impl && impl->m_fd != INVALID_SOCKET )
247             impl->ReenableEvents(wxSOCKET_OUTPUT_FLAG);
248     }
249 
250 private:
251     wxSocketBase * const m_socket;
252 
253     wxDECLARE_NO_COPY_CLASS(wxSocketWriteGuard);
254 };
255 
256 // ============================================================================
257 // wxSocketManager
258 // ============================================================================
259 
260 wxSocketManager *wxSocketManager::ms_manager = NULL;
261 
262 /* static */
Set(wxSocketManager * manager)263 void wxSocketManager::Set(wxSocketManager *manager)
264 {
265     wxASSERT_MSG( !ms_manager, "too late to set manager now" );
266 
267     ms_manager = manager;
268 }
269 
270 /* static */
Init()271 void wxSocketManager::Init()
272 {
273     wxASSERT_MSG( !ms_manager, "shouldn't be initialized twice" );
274 
275     /*
276         Details: Initialize() creates a hidden window as a sink for socket
277         events, such as 'read completed'. wxMSW has only one message loop
278         for the main thread. If Initialize is called in a secondary thread,
279         the socket window will be created for the secondary thread, but
280         since there is no message loop on this thread, it will never
281         receive events and all socket operations will time out.
282         BTW, the main thread must not be stopped using sleep or block
283         on a semaphore (a bad idea in any case) or socket operations
284         will time out.
285 
286         On the Mac side, Initialize() stores a pointer to the CFRunLoop for
287         the main thread. Because secondary threads do not have run loops,
288         adding event notifications to the "Current" loop would have no
289         effect at all, events would never fire.
290     */
291     wxASSERT_MSG( wxIsMainThread(),
292                     "sockets must be initialized from the main thread" );
293 
294     wxAppConsole * const app = wxAppConsole::GetInstance();
295     wxCHECK_RET( app, "sockets can't be initialized without wxApp" );
296 
297     ms_manager = app->GetTraits()->GetSocketManager();
298 }
299 
300 // ==========================================================================
301 // wxSocketImpl
302 // ==========================================================================
303 
wxSocketImpl(wxSocketBase & wxsocket)304 wxSocketImpl::wxSocketImpl(wxSocketBase& wxsocket)
305     : m_wxsocket(&wxsocket)
306 {
307     m_fd              = INVALID_SOCKET;
308     m_error           = wxSOCKET_NOERROR;
309     m_server          = false;
310     m_stream          = true;
311 
312     SetTimeout(wxsocket.GetTimeout() * 1000);
313 
314     m_establishing    = false;
315     m_reusable        = false;
316     m_broadcast       = false;
317     m_dobind          = true;
318     m_initialRecvBufferSize = -1;
319     m_initialSendBufferSize = -1;
320 }
321 
~wxSocketImpl()322 wxSocketImpl::~wxSocketImpl()
323 {
324     if ( m_fd != INVALID_SOCKET )
325         Shutdown();
326 }
327 
PreCreateCheck(const wxSockAddressImpl & addr)328 bool wxSocketImpl::PreCreateCheck(const wxSockAddressImpl& addr)
329 {
330     if ( m_fd != INVALID_SOCKET )
331     {
332         m_error = wxSOCKET_INVSOCK;
333         return false;
334     }
335 
336     if ( !addr.IsOk() )
337     {
338         m_error = wxSOCKET_INVADDR;
339         return false;
340     }
341 
342     return true;
343 }
344 
PostCreation()345 void wxSocketImpl::PostCreation()
346 {
347     // FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option
348 #ifdef SO_NOSIGPIPE
349     EnableSocketOption(SO_NOSIGPIPE);
350 #endif
351 
352     if ( m_reusable )
353         EnableSocketOption(SO_REUSEADDR);
354 
355     if ( m_broadcast )
356     {
357         wxASSERT_MSG( !m_stream, "broadcasting is for datagram sockets only" );
358 
359         EnableSocketOption(SO_BROADCAST);
360     }
361 
362     if ( m_initialRecvBufferSize >= 0 )
363         SetSocketOption(SO_RCVBUF, m_initialRecvBufferSize);
364     if ( m_initialSendBufferSize >= 0 )
365         SetSocketOption(SO_SNDBUF, m_initialSendBufferSize);
366 
367     // we always put our sockets in unblocked mode and handle blocking
368     // ourselves in DoRead/Write() if wxSOCKET_WAITALL is specified
369     UnblockAndRegisterWithEventLoop();
370 }
371 
UpdateLocalAddress()372 wxSocketError wxSocketImpl::UpdateLocalAddress()
373 {
374     if ( !m_local.IsOk() )
375     {
376         // ensure that we have a valid object using the correct family: correct
377         // being the same one as our peer uses as we have no other way to
378         // determine it
379         m_local.Create(m_peer.GetFamily());
380     }
381 
382     WX_SOCKLEN_T lenAddr = m_local.GetLen();
383     if ( getsockname(m_fd, m_local.GetWritableAddr(), &lenAddr) != 0 )
384     {
385         Close();
386         m_error = wxSOCKET_IOERR;
387         return m_error;
388     }
389 
390     return wxSOCKET_NOERROR;
391 }
392 
CreateServer()393 wxSocketError wxSocketImpl::CreateServer()
394 {
395     if ( !PreCreateCheck(m_local) )
396         return m_error;
397 
398     m_server = true;
399     m_stream = true;
400 
401     // do create the socket
402     m_fd = socket(m_local.GetFamily(), SOCK_STREAM, 0);
403 
404     if ( m_fd == INVALID_SOCKET )
405     {
406         m_error = wxSOCKET_IOERR;
407         return wxSOCKET_IOERR;
408     }
409 
410     PostCreation();
411 
412     // and then bind to and listen on it
413     //
414     // FIXME: should we test for m_dobind here?
415     if ( bind(m_fd, m_local.GetAddr(), m_local.GetLen()) != 0 )
416         m_error = wxSOCKET_IOERR;
417 
418     if ( IsOk() )
419     {
420         if ( listen(m_fd, 5) != 0 )
421             m_error = wxSOCKET_IOERR;
422     }
423 
424     if ( !IsOk() )
425     {
426         Close();
427         return m_error;
428     }
429 
430     // finally retrieve the address we effectively bound to
431     return UpdateLocalAddress();
432 }
433 
CreateClient(bool wait)434 wxSocketError wxSocketImpl::CreateClient(bool wait)
435 {
436     if ( !PreCreateCheck(m_peer) )
437         return m_error;
438 
439     m_fd = socket(m_peer.GetFamily(), SOCK_STREAM, 0);
440 
441     if ( m_fd == INVALID_SOCKET )
442     {
443         m_error = wxSOCKET_IOERR;
444         return wxSOCKET_IOERR;
445     }
446 
447     PostCreation();
448 
449     // If a local address has been set, then bind to it before calling connect
450     if ( m_local.IsOk() )
451     {
452         if ( bind(m_fd, m_local.GetAddr(), m_local.GetLen()) != 0 )
453         {
454             Close();
455             m_error = wxSOCKET_IOERR;
456             return m_error;
457         }
458     }
459 
460     // Do connect now
461     int rc = connect(m_fd, m_peer.GetAddr(), m_peer.GetLen());
462     if ( rc == SOCKET_ERROR )
463     {
464         wxSocketError err = GetLastError();
465         if ( err == wxSOCKET_WOULDBLOCK )
466         {
467             m_establishing = true;
468 
469             // block waiting for connection if we should (otherwise just return
470             // wxSOCKET_WOULDBLOCK to the caller)
471             if ( wait )
472             {
473                 err = SelectWithTimeout(wxSOCKET_CONNECTION_FLAG)
474                         ? wxSOCKET_NOERROR
475                         : wxSOCKET_TIMEDOUT;
476                 m_establishing = false;
477             }
478         }
479 
480         m_error = err;
481     }
482     else // connected
483     {
484         m_error = wxSOCKET_NOERROR;
485     }
486 
487     return m_error;
488 }
489 
490 
CreateUDP()491 wxSocketError wxSocketImpl::CreateUDP()
492 {
493     if ( !PreCreateCheck(m_local) )
494         return m_error;
495 
496     m_stream = false;
497     m_server = false;
498 
499     m_fd = socket(m_local.GetFamily(), SOCK_DGRAM, 0);
500 
501     if ( m_fd == INVALID_SOCKET )
502     {
503         m_error = wxSOCKET_IOERR;
504         return wxSOCKET_IOERR;
505     }
506 
507     PostCreation();
508 
509     if ( m_dobind )
510     {
511         if ( bind(m_fd, m_local.GetAddr(), m_local.GetLen()) != 0 )
512         {
513             Close();
514             m_error = wxSOCKET_IOERR;
515             return m_error;
516         }
517 
518         return UpdateLocalAddress();
519     }
520 
521     return wxSOCKET_NOERROR;
522 }
523 
Accept(wxSocketBase & wxsocket)524 wxSocketImpl *wxSocketImpl::Accept(wxSocketBase& wxsocket)
525 {
526     wxSockAddressStorage from;
527     WX_SOCKLEN_T fromlen = sizeof(from);
528     const wxSOCKET_T fd = accept(m_fd, &from.addr, &fromlen);
529 
530     // accepting is similar to reading in the sense that it resets "ready for
531     // read" flag on the socket
532     ReenableEvents(wxSOCKET_INPUT_FLAG);
533 
534     if ( fd == INVALID_SOCKET )
535         return NULL;
536 
537     wxSocketManager * const manager = wxSocketManager::Get();
538     if ( !manager )
539         return NULL;
540 
541     wxSocketImpl * const sock = manager->CreateSocket(wxsocket);
542     if ( !sock )
543         return NULL;
544 
545     sock->m_fd = fd;
546     sock->m_peer = wxSockAddressImpl(from.addr, fromlen);
547 
548     sock->UnblockAndRegisterWithEventLoop();
549 
550     return sock;
551 }
552 
553 
Close()554 void wxSocketImpl::Close()
555 {
556     if ( m_fd != INVALID_SOCKET )
557     {
558         DoClose();
559         m_fd = INVALID_SOCKET;
560     }
561 }
562 
Shutdown()563 void wxSocketImpl::Shutdown()
564 {
565     if ( m_fd != INVALID_SOCKET )
566     {
567         shutdown(m_fd, 1 /* SD_SEND */);
568         Close();
569     }
570 }
571 
572 /*
573  *  Sets the timeout for blocking calls. Time is expressed in
574  *  milliseconds.
575  */
SetTimeout(unsigned long millis)576 void wxSocketImpl::SetTimeout(unsigned long millis)
577 {
578     SetTimeValFromMS(m_timeout, millis);
579 }
580 
NotifyOnStateChange(wxSocketNotify event)581 void wxSocketImpl::NotifyOnStateChange(wxSocketNotify event)
582 {
583     m_wxsocket->OnRequest(event);
584 }
585 
586 /* Address handling */
SetLocal(const wxSockAddressImpl & local)587 wxSocketError wxSocketImpl::SetLocal(const wxSockAddressImpl& local)
588 {
589     /* the socket must be initialized, or it must be a server */
590     if (m_fd != INVALID_SOCKET && !m_server)
591     {
592         m_error = wxSOCKET_INVSOCK;
593         return wxSOCKET_INVSOCK;
594     }
595 
596     if ( !local.IsOk() )
597     {
598         m_error = wxSOCKET_INVADDR;
599         return wxSOCKET_INVADDR;
600     }
601 
602     m_local = local;
603 
604     return wxSOCKET_NOERROR;
605 }
606 
SetPeer(const wxSockAddressImpl & peer)607 wxSocketError wxSocketImpl::SetPeer(const wxSockAddressImpl& peer)
608 {
609     if ( !peer.IsOk() )
610     {
611         m_error = wxSOCKET_INVADDR;
612         return wxSOCKET_INVADDR;
613     }
614 
615     m_peer = peer;
616 
617     return wxSOCKET_NOERROR;
618 }
619 
GetLocal()620 const wxSockAddressImpl& wxSocketImpl::GetLocal()
621 {
622     if ( !m_local.IsOk() )
623         UpdateLocalAddress();
624 
625     return m_local;
626 }
627 
628 // ----------------------------------------------------------------------------
629 // wxSocketImpl IO
630 // ----------------------------------------------------------------------------
631 
632 // this macro wraps the given expression (normally a syscall) in a loop which
633 // ignores any interruptions, i.e. reevaluates it again if it failed and errno
634 // is EINTR
635 #ifdef __UNIX__
636     #define DO_WHILE_EINTR( rc, syscall ) \
637         do { \
638             rc = (syscall); \
639         } \
640         while ( rc == -1 && errno == EINTR )
641 #else
642     #define DO_WHILE_EINTR( rc, syscall ) rc = (syscall)
643 #endif
644 
RecvStream(void * buffer,int size)645 int wxSocketImpl::RecvStream(void *buffer, int size)
646 {
647     int ret;
648     DO_WHILE_EINTR( ret, recv(m_fd, static_cast<char *>(buffer), size, 0) );
649 
650     if ( !ret )
651     {
652         // receiving 0 bytes for a TCP socket indicates that the connection was
653         // closed by peer so shut down our end as well (for UDP sockets empty
654         // datagrams are also possible)
655         m_establishing = false;
656         NotifyOnStateChange(wxSOCKET_LOST);
657 
658         Shutdown();
659 
660         // do not return an error in this case however
661     }
662 
663     return ret;
664 }
665 
SendStream(const void * buffer,int size)666 int wxSocketImpl::SendStream(const void *buffer, int size)
667 {
668 #ifdef wxNEEDS_IGNORE_SIGPIPE
669     IgnoreSignal ignore(SIGPIPE);
670 #endif
671 
672     int ret;
673     DO_WHILE_EINTR( ret, send(m_fd, static_cast<const char *>(buffer), size,
674                               wxSOCKET_MSG_NOSIGNAL) );
675 
676     return ret;
677 }
678 
RecvDgram(void * buffer,int size)679 int wxSocketImpl::RecvDgram(void *buffer, int size)
680 {
681     wxSockAddressStorage from;
682     WX_SOCKLEN_T fromlen = sizeof(from);
683 
684     int ret;
685     DO_WHILE_EINTR( ret, recvfrom(m_fd, static_cast<char *>(buffer), size,
686                                   0, &from.addr, &fromlen) );
687 
688     if ( ret == SOCKET_ERROR )
689         return SOCKET_ERROR;
690 
691     m_peer = wxSockAddressImpl(from.addr, fromlen);
692     if ( !m_peer.IsOk() )
693         return -1;
694 
695     return ret;
696 }
697 
SendDgram(const void * buffer,int size)698 int wxSocketImpl::SendDgram(const void *buffer, int size)
699 {
700     if ( !m_peer.IsOk() )
701     {
702         m_error = wxSOCKET_INVADDR;
703         return -1;
704     }
705 
706     int ret;
707     DO_WHILE_EINTR( ret, sendto(m_fd, static_cast<const char *>(buffer), size,
708                                 0, m_peer.GetAddr(), m_peer.GetLen()) );
709 
710     return ret;
711 }
712 
Read(void * buffer,int size)713 int wxSocketImpl::Read(void *buffer, int size)
714 {
715     // server sockets can't be used for IO, only to accept new connections
716     if ( m_fd == INVALID_SOCKET || m_server )
717     {
718         m_error = wxSOCKET_INVSOCK;
719         return -1;
720     }
721 
722     int ret = m_stream ? RecvStream(buffer, size)
723                        : RecvDgram(buffer, size);
724 
725     m_error = ret == SOCKET_ERROR ? GetLastError() : wxSOCKET_NOERROR;
726 
727     return ret;
728 }
729 
Write(const void * buffer,int size)730 int wxSocketImpl::Write(const void *buffer, int size)
731 {
732     if ( m_fd == INVALID_SOCKET || m_server )
733     {
734         m_error = wxSOCKET_INVSOCK;
735         return -1;
736     }
737 
738     int ret = m_stream ? SendStream(buffer, size)
739                        : SendDgram(buffer, size);
740 
741     m_error = ret == SOCKET_ERROR ? GetLastError() : wxSOCKET_NOERROR;
742 
743     return ret;
744 }
745 
746 // ==========================================================================
747 // wxSocketBase
748 // ==========================================================================
749 
750 // --------------------------------------------------------------------------
751 // Initialization and shutdown
752 // --------------------------------------------------------------------------
753 
754 namespace
755 {
756 
757 // counts the number of calls to Initialize() minus the number of calls to
758 // Shutdown(): we don't really need it any more but it was documented that
759 // Shutdown() must be called the same number of times as Initialize() and using
760 // a counter helps us to check it
761 int gs_socketInitCount = 0;
762 
763 } // anonymous namespace
764 
IsInitialized()765 bool wxSocketBase::IsInitialized()
766 {
767     wxASSERT_MSG( wxIsMainThread(), "unsafe to call from other threads" );
768 
769     return gs_socketInitCount != 0;
770 }
771 
Initialize()772 bool wxSocketBase::Initialize()
773 {
774     wxCHECK_MSG( wxIsMainThread(), false,
775                  "must be called from the main thread" );
776 
777     if ( !gs_socketInitCount )
778     {
779         wxSocketManager * const manager = wxSocketManager::Get();
780         if ( !manager || !manager->OnInit() )
781             return false;
782     }
783 
784     gs_socketInitCount++;
785 
786     return true;
787 }
788 
Shutdown()789 void wxSocketBase::Shutdown()
790 {
791     wxCHECK_RET( wxIsMainThread(), "must be called from the main thread" );
792 
793     wxCHECK_RET( gs_socketInitCount > 0, "too many calls to Shutdown()" );
794 
795     if ( !--gs_socketInitCount )
796     {
797         wxSocketManager * const manager = wxSocketManager::Get();
798         wxCHECK_RET( manager, "should have a socket manager" );
799 
800         manager->OnExit();
801     }
802 }
803 
804 // --------------------------------------------------------------------------
805 // Ctor and dtor
806 // --------------------------------------------------------------------------
807 
Init()808 void wxSocketBase::Init()
809 {
810     m_impl         = NULL;
811     m_type         = wxSOCKET_UNINIT;
812 
813     // state
814     m_flags        = 0;
815     m_connected    =
816     m_establishing =
817     m_reading      =
818     m_writing      =
819     m_closed       = false;
820     m_lcount       = 0;
821     m_lcount_read  = 0;
822     m_lcount_write = 0;
823     m_timeout      = 600;
824     m_beingDeleted = false;
825 
826     // pushback buffer
827     m_unread       = NULL;
828     m_unrd_size    = 0;
829     m_unrd_cur     = 0;
830 
831     // events
832     m_id           = wxID_ANY;
833     m_handler      = NULL;
834     m_clientData   = NULL;
835     m_notify       = false;
836     m_eventmask    =
837     m_eventsgot    = 0;
838 
839     // when we create the first socket in the main thread we initialize the
840     // OS-dependent socket stuff: notice that this means that the user code
841     // needs to call wxSocket::Initialize() itself if the first socket it
842     // creates is not created in the main thread
843     if ( wxIsMainThread() )
844     {
845         if ( !Initialize() )
846         {
847             wxLogError(_("Cannot initialize sockets"));
848         }
849     }
850 }
851 
wxSocketBase()852 wxSocketBase::wxSocketBase()
853 {
854     Init();
855 }
856 
wxSocketBase(wxSocketFlags flags,wxSocketType type)857 wxSocketBase::wxSocketBase(wxSocketFlags flags, wxSocketType type)
858 {
859     Init();
860 
861     SetFlags(flags);
862 
863     m_type = type;
864 }
865 
~wxSocketBase()866 wxSocketBase::~wxSocketBase()
867 {
868     // Shutdown and close the socket
869     if (!m_beingDeleted)
870         Close();
871 
872     // Destroy the implementation object
873     delete m_impl;
874 
875     // Free the pushback buffer
876     free(m_unread);
877 }
878 
Destroy()879 bool wxSocketBase::Destroy()
880 {
881     // Delayed destruction: the socket will be deleted during the next idle
882     // loop iteration. This ensures that all pending events have been
883     // processed.
884     m_beingDeleted = true;
885 
886     // Shutdown and close the socket
887     Close();
888 
889     // Suppress events from now on
890     Notify(false);
891 
892     // Schedule this object for deletion instead of destroying it right now if
893     // it can have other events pending for it and we have a way to do it.
894     //
895     // Notice that sockets used in other threads won't have any events for them
896     // and we shouldn't use delayed destruction mechanism for them as it's not
897     // MT-safe.
898     if ( wxIsMainThread() && wxTheApp )
899     {
900         wxTheApp->ScheduleForDestruction(this);
901     }
902     else // no app
903     {
904         // in wxBase we might have no app object at all, don't leak memory
905         delete this;
906     }
907 
908     return true;
909 }
910 
911 // ----------------------------------------------------------------------------
912 // simple accessors
913 // ----------------------------------------------------------------------------
914 
SetError(wxSocketError error)915 void wxSocketBase::SetError(wxSocketError error)
916 {
917     m_impl->m_error = error;
918 }
919 
LastError() const920 wxSocketError wxSocketBase::LastError() const
921 {
922     return m_impl->GetError();
923 }
924 
925 // --------------------------------------------------------------------------
926 // Basic IO calls
927 // --------------------------------------------------------------------------
928 
929 // The following IO operations update m_lcount:
930 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
Close()931 bool wxSocketBase::Close()
932 {
933     // Interrupt pending waits
934     InterruptWait();
935 
936     ShutdownOutput();
937 
938     m_connected = false;
939     m_establishing = false;
940     return true;
941 }
942 
ShutdownOutput()943 void wxSocketBase::ShutdownOutput()
944 {
945     if ( m_impl )
946         m_impl->Shutdown();
947 }
948 
Read(void * buffer,wxUint32 nbytes)949 wxSocketBase& wxSocketBase::Read(void* buffer, wxUint32 nbytes)
950 {
951     wxSocketReadGuard read(this);
952 
953     m_lcount_read = DoRead(buffer, nbytes);
954     m_lcount = m_lcount_read;
955 
956     return *this;
957 }
958 
DoRead(void * buffer_,wxUint32 nbytes)959 wxUint32 wxSocketBase::DoRead(void* buffer_, wxUint32 nbytes)
960 {
961     wxCHECK_MSG( m_impl, 0, "socket must be valid" );
962 
963     // We use pointer arithmetic here which doesn't work with void pointers.
964     char *buffer = static_cast<char *>(buffer_);
965     wxCHECK_MSG( buffer, 0, "NULL buffer" );
966 
967     // Try the push back buffer first, even before checking whether the socket
968     // is valid to allow reading previously pushed back data from an already
969     // closed socket.
970     wxUint32 total = GetPushback(buffer, nbytes, false);
971     nbytes -= total;
972     buffer += total;
973 
974     while ( nbytes )
975     {
976         // our socket is non-blocking so Read() will return immediately if
977         // there is nothing to read yet and it's more efficient to try it first
978         // before entering DoWait() which is going to start dispatching GUI
979         // events and, even more importantly, we must do this under Windows
980         // where we're not going to get notifications about socket being ready
981         // for reading before we read all the existing data from it
982         const int ret = !m_impl->m_stream || m_connected
983                             ? m_impl->Read(buffer, nbytes)
984                             : 0;
985         if ( ret == -1 )
986         {
987             if ( m_impl->GetLastError() == wxSOCKET_WOULDBLOCK )
988             {
989                 // if we don't want to wait, just return immediately
990                 if ( m_flags & wxSOCKET_NOWAIT_READ )
991                 {
992                     // this shouldn't be counted as an error in this case
993                     SetError(wxSOCKET_NOERROR);
994                     break;
995                 }
996 
997                 // otherwise wait until the socket becomes ready for reading or
998                 // an error occurs on it
999                 if ( !DoWaitWithTimeout(wxSOCKET_INPUT_FLAG) )
1000                 {
1001                     // and exit if the timeout elapsed before it did
1002                     SetError(wxSOCKET_TIMEDOUT);
1003                     break;
1004                 }
1005 
1006                 // retry reading
1007                 continue;
1008             }
1009             else // "real" error
1010             {
1011                 SetError(wxSOCKET_IOERR);
1012                 break;
1013             }
1014         }
1015         else if ( ret == 0 )
1016         {
1017             // for connection-oriented (e.g. TCP) sockets we can only read
1018             // 0 bytes if the other end has been closed, and for connectionless
1019             // ones (UDP) this flag doesn't make sense anyhow so we can set it
1020             // to true too without doing any harm
1021             m_closed = true;
1022 
1023             // we're not going to read anything else and so if we haven't read
1024             // anything (or not everything in wxSOCKET_WAITALL case) already,
1025             // signal an error
1026             if ( (m_flags & wxSOCKET_WAITALL_READ) || !total )
1027                 SetError(wxSOCKET_IOERR);
1028             break;
1029         }
1030 
1031         total += ret;
1032 
1033         // if we are happy to read something and not the entire nbytes bytes,
1034         // then we're done
1035         if ( !(m_flags & wxSOCKET_WAITALL_READ) )
1036             break;
1037 
1038         nbytes -= ret;
1039         buffer += ret;
1040     }
1041 
1042     return total;
1043 }
1044 
ReadMsg(void * buffer,wxUint32 nbytes)1045 wxSocketBase& wxSocketBase::ReadMsg(void* buffer, wxUint32 nbytes)
1046 {
1047     struct
1048     {
1049         unsigned char sig[4];
1050         unsigned char len[4];
1051     } msg;
1052 
1053     wxSocketReadGuard read(this);
1054 
1055     wxSocketWaitModeChanger changeFlags(this, wxSOCKET_WAITALL_READ);
1056 
1057     bool ok = false;
1058     if ( DoRead(&msg, sizeof(msg)) == sizeof(msg) )
1059     {
1060         wxUint32 sig = (wxUint32)msg.sig[0];
1061         sig |= (wxUint32)(msg.sig[1] << 8);
1062         sig |= (wxUint32)(msg.sig[2] << 16);
1063         sig |= (wxUint32)(msg.sig[3] << 24);
1064 
1065         if ( sig == 0xfeeddead )
1066         {
1067             wxUint32 len = (wxUint32)msg.len[0];
1068             len |= (wxUint32)(msg.len[1] << 8);
1069             len |= (wxUint32)(msg.len[2] << 16);
1070             len |= (wxUint32)(msg.len[3] << 24);
1071 
1072             wxUint32 len2;
1073             if (len > nbytes)
1074             {
1075                 len2 = len - nbytes;
1076                 len = nbytes;
1077             }
1078             else
1079                 len2 = 0;
1080 
1081             // Don't attempt to read if the msg was zero bytes long.
1082             m_lcount_read = len ? DoRead(buffer, len) : 0;
1083             m_lcount = m_lcount_read;
1084 
1085             if ( len2 )
1086             {
1087                 char discard_buffer[MAX_DISCARD_SIZE];
1088                 long discard_len;
1089 
1090                 // NOTE: discarded bytes don't add to m_lcount.
1091                 do
1092                 {
1093                     discard_len = len2 > MAX_DISCARD_SIZE
1094                                     ? MAX_DISCARD_SIZE
1095                                     : len2;
1096                     discard_len = DoRead(discard_buffer, (wxUint32)discard_len);
1097                     len2 -= (wxUint32)discard_len;
1098                 }
1099                 while ((discard_len > 0) && len2);
1100             }
1101 
1102             if ( !len2 && DoRead(&msg, sizeof(msg)) == sizeof(msg) )
1103             {
1104                 sig = (wxUint32)msg.sig[0];
1105                 sig |= (wxUint32)(msg.sig[1] << 8);
1106                 sig |= (wxUint32)(msg.sig[2] << 16);
1107                 sig |= (wxUint32)(msg.sig[3] << 24);
1108 
1109                 if ( sig == 0xdeadfeed )
1110                     ok = true;
1111             }
1112         }
1113     }
1114 
1115     if ( !ok )
1116         SetError(wxSOCKET_IOERR);
1117 
1118     return *this;
1119 }
1120 
Peek(void * buffer,wxUint32 nbytes)1121 wxSocketBase& wxSocketBase::Peek(void* buffer, wxUint32 nbytes)
1122 {
1123     wxSocketReadGuard read(this);
1124 
1125     // Peek() should never block
1126     wxSocketWaitModeChanger changeFlags(this, wxSOCKET_NOWAIT);
1127 
1128     m_lcount = DoRead(buffer, nbytes);
1129 
1130     Pushback(buffer, m_lcount);
1131 
1132     return *this;
1133 }
1134 
Write(const void * buffer,wxUint32 nbytes)1135 wxSocketBase& wxSocketBase::Write(const void *buffer, wxUint32 nbytes)
1136 {
1137     wxSocketWriteGuard write(this);
1138 
1139     m_lcount_write = DoWrite(buffer, nbytes);
1140     m_lcount = m_lcount_write;
1141 
1142     return *this;
1143 }
1144 
1145 // This function is a mirror image of DoRead() except that it doesn't use the
1146 // push back buffer and doesn't treat 0 return value specially (normally this
1147 // shouldn't happen at all here), so please see comments there for explanations
DoWrite(const void * buffer_,wxUint32 nbytes)1148 wxUint32 wxSocketBase::DoWrite(const void *buffer_, wxUint32 nbytes)
1149 {
1150     wxCHECK_MSG( m_impl, 0, "socket must be valid" );
1151 
1152     const char *buffer = static_cast<const char *>(buffer_);
1153     wxCHECK_MSG( buffer, 0, "NULL buffer" );
1154 
1155     wxUint32 total = 0;
1156     while ( nbytes )
1157     {
1158         if ( m_impl->m_stream && !m_connected )
1159         {
1160             if ( (m_flags & wxSOCKET_WAITALL_WRITE) || !total )
1161                 SetError(wxSOCKET_IOERR);
1162             break;
1163         }
1164 
1165         const int ret = m_impl->Write(buffer, nbytes);
1166         if ( ret == -1 )
1167         {
1168             if ( m_impl->GetLastError() == wxSOCKET_WOULDBLOCK )
1169             {
1170                 if ( m_flags & wxSOCKET_NOWAIT_WRITE )
1171                     break;
1172 
1173                 if ( !DoWaitWithTimeout(wxSOCKET_OUTPUT_FLAG) )
1174                 {
1175                     SetError(wxSOCKET_TIMEDOUT);
1176                     break;
1177                 }
1178 
1179                 continue;
1180             }
1181             else // "real" error
1182             {
1183                 SetError(wxSOCKET_IOERR);
1184                 break;
1185             }
1186         }
1187 
1188         total += ret;
1189 
1190         if ( !(m_flags & wxSOCKET_WAITALL_WRITE) )
1191             break;
1192 
1193         nbytes -= ret;
1194         buffer += ret;
1195     }
1196 
1197     return total;
1198 }
1199 
WriteMsg(const void * buffer,wxUint32 nbytes)1200 wxSocketBase& wxSocketBase::WriteMsg(const void *buffer, wxUint32 nbytes)
1201 {
1202     struct
1203     {
1204         unsigned char sig[4];
1205         unsigned char len[4];
1206     } msg;
1207 
1208     wxSocketWriteGuard write(this);
1209 
1210     wxSocketWaitModeChanger changeFlags(this, wxSOCKET_WAITALL_WRITE);
1211 
1212     msg.sig[0] = (unsigned char) 0xad;
1213     msg.sig[1] = (unsigned char) 0xde;
1214     msg.sig[2] = (unsigned char) 0xed;
1215     msg.sig[3] = (unsigned char) 0xfe;
1216 
1217     msg.len[0] = (unsigned char) (nbytes & 0xff);
1218     msg.len[1] = (unsigned char) ((nbytes >> 8) & 0xff);
1219     msg.len[2] = (unsigned char) ((nbytes >> 16) & 0xff);
1220     msg.len[3] = (unsigned char) ((nbytes >> 24) & 0xff);
1221 
1222     bool ok = false;
1223     if ( DoWrite(&msg, sizeof(msg)) == sizeof(msg) )
1224     {
1225         m_lcount_write = DoWrite(buffer, nbytes);
1226         m_lcount = m_lcount_write;
1227         if ( m_lcount_write == nbytes )
1228         {
1229             msg.sig[0] = (unsigned char) 0xed;
1230             msg.sig[1] = (unsigned char) 0xfe;
1231             msg.sig[2] = (unsigned char) 0xad;
1232             msg.sig[3] = (unsigned char) 0xde;
1233             msg.len[0] =
1234             msg.len[1] =
1235             msg.len[2] =
1236             msg.len[3] = (char) 0;
1237 
1238             if ( DoWrite(&msg, sizeof(msg)) == sizeof(msg))
1239                 ok = true;
1240         }
1241     }
1242 
1243     if ( !ok )
1244         SetError(wxSOCKET_IOERR);
1245 
1246     return *this;
1247 }
1248 
Unread(const void * buffer,wxUint32 nbytes)1249 wxSocketBase& wxSocketBase::Unread(const void *buffer, wxUint32 nbytes)
1250 {
1251     if (nbytes != 0)
1252         Pushback(buffer, nbytes);
1253 
1254     SetError(wxSOCKET_NOERROR);
1255     m_lcount = nbytes;
1256 
1257     return *this;
1258 }
1259 
Discard()1260 wxSocketBase& wxSocketBase::Discard()
1261 {
1262     char *buffer = new char[MAX_DISCARD_SIZE];
1263     wxUint32 ret;
1264     wxUint32 total = 0;
1265 
1266     wxSocketReadGuard read(this);
1267 
1268     wxSocketWaitModeChanger changeFlags(this, wxSOCKET_NOWAIT);
1269 
1270     do
1271     {
1272         ret = DoRead(buffer, MAX_DISCARD_SIZE);
1273         total += ret;
1274     }
1275     while (ret == MAX_DISCARD_SIZE);
1276 
1277     delete[] buffer;
1278     m_lcount = total;
1279     SetError(wxSOCKET_NOERROR);
1280 
1281     return *this;
1282 }
1283 
1284 // --------------------------------------------------------------------------
1285 // Wait functions
1286 // --------------------------------------------------------------------------
1287 
1288 /*
1289     This function will check for the events specified in the flags parameter,
1290     and it will return a mask indicating which operations can be performed.
1291  */
Select(wxSocketEventFlags flags,const timeval * timeout)1292 wxSocketEventFlags wxSocketImpl::Select(wxSocketEventFlags flags,
1293                                         const timeval *timeout)
1294 {
1295     if ( m_fd == INVALID_SOCKET )
1296         return (wxSOCKET_LOST_FLAG & flags);
1297 
1298     struct timeval tv;
1299     if ( timeout )
1300         tv = *timeout;
1301     else
1302         tv.tv_sec = tv.tv_usec = 0;
1303 
1304     // prepare the FD sets, passing NULL for the one(s) we don't use
1305     fd_set
1306         readfds, *preadfds = NULL,
1307         writefds, *pwritefds = NULL,
1308         exceptfds;                      // always want to know about errors
1309 
1310     if ( flags & wxSOCKET_INPUT_FLAG )
1311         preadfds = &readfds;
1312 
1313     if ( flags & wxSOCKET_OUTPUT_FLAG )
1314         pwritefds = &writefds;
1315 
1316     // When using non-blocking connect() the client socket becomes connected
1317     // (successfully or not) when it becomes writable but when using
1318     // non-blocking accept() the server socket becomes connected when it
1319     // becomes readable.
1320     if ( flags & wxSOCKET_CONNECTION_FLAG )
1321     {
1322         if ( m_server )
1323             preadfds = &readfds;
1324         else
1325             pwritefds = &writefds;
1326     }
1327 
1328     if ( preadfds )
1329     {
1330         wxFD_ZERO(preadfds);
1331         wxFD_SET(m_fd, preadfds);
1332     }
1333 
1334     if ( pwritefds )
1335     {
1336         wxFD_ZERO(pwritefds);
1337         wxFD_SET(m_fd, pwritefds);
1338     }
1339 
1340     wxFD_ZERO(&exceptfds);
1341     wxFD_SET(m_fd, &exceptfds);
1342 
1343     const int rc = select(m_fd + 1, preadfds, pwritefds, &exceptfds, &tv);
1344 
1345     // check for errors first
1346     if ( rc == -1 || wxFD_ISSET(m_fd, &exceptfds) )
1347     {
1348         m_establishing = false;
1349 
1350         return wxSOCKET_LOST_FLAG & flags;
1351     }
1352 
1353     if ( rc == 0 )
1354         return 0;
1355 
1356     wxASSERT_MSG( rc == 1, "unexpected select() return value" );
1357 
1358     wxSocketEventFlags detected = 0;
1359     if ( preadfds && wxFD_ISSET(m_fd, preadfds) )
1360     {
1361         // check for the case of a server socket waiting for connection
1362         if ( m_server && (flags & wxSOCKET_CONNECTION_FLAG) )
1363         {
1364             int error;
1365             SOCKOPTLEN_T len = sizeof(error);
1366             m_establishing = false;
1367             getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
1368 
1369             if ( error )
1370                 detected = wxSOCKET_LOST_FLAG;
1371             else
1372                 detected |= wxSOCKET_CONNECTION_FLAG;
1373         }
1374         else // not called to get non-blocking accept() status
1375         {
1376             detected |= wxSOCKET_INPUT_FLAG;
1377         }
1378     }
1379 
1380     if ( pwritefds && wxFD_ISSET(m_fd, pwritefds) )
1381     {
1382         // check for the case of non-blocking connect()
1383         if ( m_establishing && !m_server )
1384         {
1385             int error;
1386             SOCKOPTLEN_T len = sizeof(error);
1387             m_establishing = false;
1388             getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
1389 
1390             if ( error )
1391                 detected = wxSOCKET_LOST_FLAG;
1392             else
1393                 detected |= wxSOCKET_CONNECTION_FLAG;
1394         }
1395         else // not called to get non-blocking connect() status
1396         {
1397             detected |= wxSOCKET_OUTPUT_FLAG;
1398         }
1399     }
1400 
1401     return detected & flags;
1402 }
1403 
1404 int
DoWait(long seconds,long milliseconds,wxSocketEventFlags flags)1405 wxSocketBase::DoWait(long seconds, long milliseconds, wxSocketEventFlags flags)
1406 {
1407     // Use either the provided timeout or the default timeout value associated
1408     // with this socket.
1409     //
1410     // TODO: allow waiting forever, see #9443
1411     const long timeout = seconds == -1 ? m_timeout * 1000
1412                                        : seconds * 1000 + milliseconds;
1413 
1414     return DoWait(timeout, flags);
1415 }
1416 
1417 int
DoWait(long timeout,wxSocketEventFlags flags)1418 wxSocketBase::DoWait(long timeout, wxSocketEventFlags flags)
1419 {
1420     wxCHECK_MSG( m_impl, -1, "can't wait on invalid socket" );
1421 
1422     // we're never going to become ready in a TCP client if we're not connected
1423     // any more (OTOH a server can call this to precisely wait for a connection
1424     // so do wait for it in this case and UDP client is never "connected")
1425     if ( !m_impl->IsServer() &&
1426             m_impl->m_stream && !m_connected && !m_establishing )
1427         return -1;
1428 
1429     // This can be set to true from Interrupt() to exit this function a.s.a.p.
1430     m_interrupt = false;
1431 
1432 
1433     const wxMilliClock_t timeEnd = wxGetLocalTimeMillis() + timeout;
1434 
1435     // Get the active event loop which we'll use for the message dispatching
1436     // when running in the main thread unless this was explicitly disabled by
1437     // setting wxSOCKET_BLOCK flag
1438     wxEventLoopBase *eventLoop;
1439     if ( !(m_flags & wxSOCKET_BLOCK) && wxIsMainThread() )
1440     {
1441         eventLoop = wxEventLoop::GetActive();
1442     }
1443     else // in worker thread
1444     {
1445         // We never dispatch messages from threads other than the main one.
1446         eventLoop = NULL;
1447     }
1448 
1449     // Make sure the events we're interested in are enabled before waiting for
1450     // them: this is really necessary here as otherwise this could happen:
1451     //  1. DoRead(wxSOCKET_WAITALL) is called
1452     //  2. There is nothing to read so DoWait(wxSOCKET_INPUT_FLAG) is called
1453     //  3. Some, but not all data appears, wxSocketImplUnix::OnReadWaiting()
1454     //     is called and wxSOCKET_INPUT_FLAG events are disabled in it
1455     //  4. Because of wxSOCKET_WAITALL we call DoWait() again but the events
1456     //     are still disabled and we block forever
1457     //
1458     // More elegant solution would be nice but for now simply re-enabling the
1459     // events here will do
1460     m_impl->ReenableEvents(flags & (wxSOCKET_INPUT_FLAG | wxSOCKET_OUTPUT_FLAG));
1461 
1462 
1463     // Wait until we receive the event we're waiting for or the timeout expires
1464     // (but note that we always execute the loop at least once, even if timeout
1465     // is 0 as this is used for polling)
1466     int rc = 0;
1467     for ( bool firstTime = true; !m_interrupt; firstTime = false )
1468     {
1469         long timeLeft = wxMilliClockToLong(timeEnd - wxGetLocalTimeMillis());
1470         if ( timeLeft < 0 )
1471         {
1472             if ( !firstTime )
1473                 break;   // timed out
1474 
1475             timeLeft = 0;
1476         }
1477 
1478         wxSocketEventFlags events;
1479         if ( eventLoop )
1480         {
1481             // reset them before starting to wait
1482             m_eventsgot = 0;
1483 
1484             eventLoop->DispatchTimeout(timeLeft);
1485 
1486             events = m_eventsgot;
1487         }
1488         else // no event loop or waiting in another thread
1489         {
1490             // as explained below, we should always check for wxSOCKET_LOST_FLAG
1491             timeval tv;
1492             SetTimeValFromMS(tv, timeLeft);
1493             events = m_impl->Select(flags | wxSOCKET_LOST_FLAG, &tv);
1494         }
1495 
1496         // always check for wxSOCKET_LOST_FLAG, even if flags doesn't include
1497         // it, as continuing to wait for anything else after getting it is
1498         // pointless
1499         if ( events & wxSOCKET_LOST_FLAG )
1500         {
1501             m_connected = false;
1502             m_establishing = false;
1503             rc = -1;
1504             break;
1505         }
1506 
1507         // otherwise mask out the bits we're not interested in
1508         events &= flags;
1509 
1510         // Incoming connection (server) or connection established (client)?
1511         if ( events & wxSOCKET_CONNECTION_FLAG )
1512         {
1513             m_connected = true;
1514             m_establishing = false;
1515             rc = true;
1516             break;
1517         }
1518 
1519         // Data available or output buffer ready?
1520         if ( (events & wxSOCKET_INPUT_FLAG) || (events & wxSOCKET_OUTPUT_FLAG) )
1521         {
1522             rc = true;
1523             break;
1524         }
1525     }
1526 
1527     return rc;
1528 }
1529 
Wait(long seconds,long milliseconds)1530 bool wxSocketBase::Wait(long seconds, long milliseconds)
1531 {
1532     return DoWait(seconds, milliseconds,
1533                   wxSOCKET_INPUT_FLAG |
1534                   wxSOCKET_OUTPUT_FLAG |
1535                   wxSOCKET_CONNECTION_FLAG) != 0;
1536 }
1537 
WaitForRead(long seconds,long milliseconds)1538 bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
1539 {
1540     // Check pushback buffer before entering DoWait
1541     if ( m_unread )
1542         return true;
1543 
1544     // Check if the socket is not already ready for input, if it is, there is
1545     // no need to start waiting for it (worse, we'll actually never get a
1546     // notification about the socket becoming ready if it is already under
1547     // Windows)
1548     if ( m_impl->Select(wxSOCKET_INPUT_FLAG) )
1549         return true;
1550 
1551     return DoWait(seconds, milliseconds, wxSOCKET_INPUT_FLAG) != 0;
1552 }
1553 
1554 
WaitForWrite(long seconds,long milliseconds)1555 bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
1556 {
1557     if ( m_impl->Select(wxSOCKET_OUTPUT_FLAG) )
1558         return true;
1559 
1560     return DoWait(seconds, milliseconds, wxSOCKET_OUTPUT_FLAG) != 0;
1561 }
1562 
WaitForLost(long seconds,long milliseconds)1563 bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
1564 {
1565     return DoWait(seconds, milliseconds, wxSOCKET_LOST_FLAG) == -1;
1566 }
1567 
1568 // --------------------------------------------------------------------------
1569 // Miscellaneous
1570 // --------------------------------------------------------------------------
1571 
1572 //
1573 // Get local or peer address
1574 //
1575 
GetPeer(wxSockAddress & addr) const1576 bool wxSocketBase::GetPeer(wxSockAddress& addr) const
1577 {
1578     wxCHECK_MSG( m_impl, false, "invalid socket" );
1579 
1580     const wxSockAddressImpl& peer = m_impl->GetPeer();
1581     if ( !peer.IsOk() )
1582         return false;
1583 
1584     addr.SetAddress(peer);
1585 
1586     return true;
1587 }
1588 
GetLocal(wxSockAddress & addr) const1589 bool wxSocketBase::GetLocal(wxSockAddress& addr) const
1590 {
1591     wxCHECK_MSG( m_impl, false, "invalid socket" );
1592 
1593     const wxSockAddressImpl& local = m_impl->GetLocal();
1594     if ( !local.IsOk() )
1595         return false;
1596 
1597     addr.SetAddress(local);
1598 
1599     return true;
1600 }
1601 
1602 //
1603 // Save and restore socket state
1604 //
1605 
SaveState()1606 void wxSocketBase::SaveState()
1607 {
1608     wxSocketState *state;
1609 
1610     state = new wxSocketState();
1611 
1612     state->m_flags      = m_flags;
1613     state->m_notify     = m_notify;
1614     state->m_eventmask  = m_eventmask;
1615     state->m_clientData = m_clientData;
1616 
1617     m_states.Append(state);
1618 }
1619 
RestoreState()1620 void wxSocketBase::RestoreState()
1621 {
1622     wxList::compatibility_iterator node;
1623     wxSocketState *state;
1624 
1625     node = m_states.GetLast();
1626     if (!node)
1627         return;
1628 
1629     state = (wxSocketState *)node->GetData();
1630 
1631     m_flags      = state->m_flags;
1632     m_notify     = state->m_notify;
1633     m_eventmask  = state->m_eventmask;
1634     m_clientData = state->m_clientData;
1635 
1636     m_states.Erase(node);
1637     delete state;
1638 }
1639 
1640 //
1641 // Timeout and flags
1642 //
1643 
SetTimeout(long seconds)1644 void wxSocketBase::SetTimeout(long seconds)
1645 {
1646     m_timeout = seconds;
1647 
1648     if (m_impl)
1649         m_impl->SetTimeout(m_timeout * 1000);
1650 }
1651 
SetFlags(wxSocketFlags flags)1652 void wxSocketBase::SetFlags(wxSocketFlags flags)
1653 {
1654     // Do some sanity checking on the flags used: not all values can be used
1655     // together.
1656     wxASSERT_MSG( !(flags & wxSOCKET_NOWAIT) ||
1657                   !(flags & (wxSOCKET_WAITALL | wxSOCKET_BLOCK)),
1658                   "Using wxSOCKET_WAITALL or wxSOCKET_BLOCK with "
1659                   "wxSOCKET_NOWAIT doesn't make sense" );
1660 
1661     m_flags = flags;
1662 }
1663 
1664 
1665 // --------------------------------------------------------------------------
1666 // Event handling
1667 // --------------------------------------------------------------------------
1668 
OnRequest(wxSocketNotify notification)1669 void wxSocketBase::OnRequest(wxSocketNotify notification)
1670 {
1671     wxSocketEventFlags flag = 0;
1672     switch ( notification )
1673     {
1674         case wxSOCKET_INPUT:
1675             flag = wxSOCKET_INPUT_FLAG;
1676             break;
1677 
1678         case wxSOCKET_OUTPUT:
1679             flag = wxSOCKET_OUTPUT_FLAG;
1680             break;
1681 
1682         case wxSOCKET_CONNECTION:
1683             flag = wxSOCKET_CONNECTION_FLAG;
1684 
1685             // we're now successfully connected
1686             m_connected = true;
1687             m_establishing = false;
1688 
1689             // error was previously set to wxSOCKET_WOULDBLOCK, but this is not
1690             // the case any longer
1691             SetError(wxSOCKET_NOERROR);
1692             break;
1693 
1694         case wxSOCKET_LOST:
1695             flag = wxSOCKET_LOST_FLAG;
1696 
1697             // if we lost the connection the socket is now closed and not
1698             // connected any more
1699             m_connected = false;
1700             m_closed = true;
1701             break;
1702 
1703         default:
1704             wxFAIL_MSG( "unknown wxSocket notification" );
1705     }
1706 
1707     // remember the events which were generated for this socket, we're going to
1708     // use this in DoWait()
1709     m_eventsgot |= flag;
1710 
1711     // send the wx event if enabled and we're interested in it
1712     if ( m_notify && (m_eventmask & flag) && m_handler )
1713     {
1714         // don't generate the events when we're inside DoWait() called from our
1715         // own code as we are going to consume the data that has just become
1716         // available ourselves and the user code won't see it at all
1717         if ( (notification == wxSOCKET_INPUT && m_reading) ||
1718                 (notification == wxSOCKET_OUTPUT && m_writing) )
1719         {
1720             return;
1721         }
1722 
1723         wxSocketEvent event(m_id);
1724         event.m_event      = notification;
1725         event.m_clientData = m_clientData;
1726         event.SetEventObject(this);
1727 
1728         m_handler->AddPendingEvent(event);
1729     }
1730 }
1731 
Notify(bool notify)1732 void wxSocketBase::Notify(bool notify)
1733 {
1734     m_notify = notify;
1735 }
1736 
SetNotify(wxSocketEventFlags flags)1737 void wxSocketBase::SetNotify(wxSocketEventFlags flags)
1738 {
1739     m_eventmask = flags;
1740 }
1741 
SetEventHandler(wxEvtHandler & handler,int id)1742 void wxSocketBase::SetEventHandler(wxEvtHandler& handler, int id)
1743 {
1744     m_handler = &handler;
1745     m_id      = id;
1746 }
1747 
1748 // --------------------------------------------------------------------------
1749 // Pushback buffer
1750 // --------------------------------------------------------------------------
1751 
Pushback(const void * buffer,wxUint32 size)1752 void wxSocketBase::Pushback(const void *buffer, wxUint32 size)
1753 {
1754     if (!size) return;
1755 
1756     if (m_unread == NULL)
1757         m_unread = malloc(size);
1758     else
1759     {
1760         void *tmp;
1761 
1762         tmp = malloc(m_unrd_size + size);
1763         memcpy((char *)tmp + size, m_unread, m_unrd_size);
1764         free(m_unread);
1765 
1766         m_unread = tmp;
1767     }
1768 
1769     m_unrd_size += size;
1770 
1771     memcpy(m_unread, buffer, size);
1772 }
1773 
GetPushback(void * buffer,wxUint32 size,bool peek)1774 wxUint32 wxSocketBase::GetPushback(void *buffer, wxUint32 size, bool peek)
1775 {
1776     wxCHECK_MSG( buffer, 0, "NULL buffer" );
1777 
1778     if (!m_unrd_size)
1779         return 0;
1780 
1781     if (size > (m_unrd_size-m_unrd_cur))
1782         size = m_unrd_size-m_unrd_cur;
1783 
1784     memcpy(buffer, (char *)m_unread + m_unrd_cur, size);
1785 
1786     if (!peek)
1787     {
1788         m_unrd_cur += size;
1789         if (m_unrd_size == m_unrd_cur)
1790         {
1791             free(m_unread);
1792             m_unread = NULL;
1793             m_unrd_size = 0;
1794             m_unrd_cur  = 0;
1795         }
1796     }
1797 
1798     return size;
1799 }
1800 
1801 
1802 // ==========================================================================
1803 // wxSocketServer
1804 // ==========================================================================
1805 
1806 // --------------------------------------------------------------------------
1807 // Ctor
1808 // --------------------------------------------------------------------------
1809 
wxSocketServer(const wxSockAddress & addr,wxSocketFlags flags)1810 wxSocketServer::wxSocketServer(const wxSockAddress& addr,
1811                                wxSocketFlags flags)
1812               : wxSocketBase(flags, wxSOCKET_SERVER)
1813 {
1814     wxLogTrace( wxTRACE_Socket, wxT("Opening wxSocketServer") );
1815 
1816     wxSocketManager * const manager = wxSocketManager::Get();
1817     m_impl = manager ? manager->CreateSocket(*this) : NULL;
1818 
1819     if (!m_impl)
1820     {
1821         wxLogTrace( wxTRACE_Socket, wxT("*** Failed to create m_impl") );
1822         return;
1823     }
1824 
1825     // Setup the socket as server
1826     m_impl->SetLocal(addr.GetAddress());
1827 
1828     if (GetFlags() & wxSOCKET_REUSEADDR) {
1829         m_impl->SetReusable();
1830     }
1831     if (GetFlags() & wxSOCKET_BROADCAST) {
1832         m_impl->SetBroadcast();
1833     }
1834     if (GetFlags() & wxSOCKET_NOBIND) {
1835         m_impl->DontDoBind();
1836     }
1837 
1838     if (m_impl->CreateServer() != wxSOCKET_NOERROR)
1839     {
1840         wxDELETE(m_impl);
1841 
1842         wxLogTrace( wxTRACE_Socket, wxT("*** CreateServer() failed") );
1843         return;
1844     }
1845 
1846     // Notice that we need a cast as wxSOCKET_T is 64 bit under Win64 and that
1847     // the cast is safe because a wxSOCKET_T is a handle and so limited to 32
1848     // (or, actually, even 24) bit values anyhow.
1849     wxLogTrace( wxTRACE_Socket, wxT("wxSocketServer on fd %u"),
1850                 static_cast<unsigned>(m_impl->m_fd) );
1851 }
1852 
1853 // --------------------------------------------------------------------------
1854 // Accept
1855 // --------------------------------------------------------------------------
1856 
AcceptWith(wxSocketBase & sock,bool wait)1857 bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait)
1858 {
1859     if ( !m_impl || (m_impl->m_fd == INVALID_SOCKET) || !m_impl->IsServer() )
1860     {
1861         wxFAIL_MSG( "can only be called for a valid server socket" );
1862 
1863         SetError(wxSOCKET_INVSOCK);
1864 
1865         return false;
1866     }
1867 
1868     if ( wait )
1869     {
1870         // wait until we get a connection
1871         if ( !m_impl->SelectWithTimeout(wxSOCKET_INPUT_FLAG) )
1872         {
1873             SetError(wxSOCKET_TIMEDOUT);
1874 
1875             return false;
1876         }
1877     }
1878 
1879     sock.m_impl = m_impl->Accept(sock);
1880 
1881     if ( !sock.m_impl )
1882     {
1883         SetError(m_impl->GetLastError());
1884 
1885         return false;
1886     }
1887 
1888     sock.m_type = wxSOCKET_BASE;
1889     sock.m_connected = true;
1890 
1891     return true;
1892 }
1893 
Accept(bool wait)1894 wxSocketBase *wxSocketServer::Accept(bool wait)
1895 {
1896     wxSocketBase* sock = new wxSocketBase();
1897 
1898     sock->SetFlags(m_flags);
1899 
1900     if (!AcceptWith(*sock, wait))
1901     {
1902         sock->Destroy();
1903         sock = NULL;
1904     }
1905 
1906     return sock;
1907 }
1908 
WaitForAccept(long seconds,long milliseconds)1909 bool wxSocketServer::WaitForAccept(long seconds, long milliseconds)
1910 {
1911     return DoWait(seconds, milliseconds, wxSOCKET_CONNECTION_FLAG) == 1;
1912 }
1913 
GetSocket() const1914 wxSOCKET_T wxSocketBase::GetSocket() const
1915 {
1916     wxASSERT_MSG( m_impl, wxS("Socket not initialised") );
1917 
1918     return m_impl->m_fd;
1919 }
1920 
1921 
GetOption(int level,int optname,void * optval,int * optlen)1922 bool wxSocketBase::GetOption(int level, int optname, void *optval, int *optlen)
1923 {
1924     wxASSERT_MSG( m_impl, wxT("Socket not initialised") );
1925 
1926     SOCKOPTLEN_T lenreal = *optlen;
1927     if ( getsockopt(m_impl->m_fd, level, optname,
1928                     static_cast<char *>(optval), &lenreal) != 0 )
1929         return false;
1930 
1931     *optlen = lenreal;
1932 
1933     return true;
1934 }
1935 
1936 bool
SetOption(int level,int optname,const void * optval,int optlen)1937 wxSocketBase::SetOption(int level, int optname, const void *optval, int optlen)
1938 {
1939     wxASSERT_MSG( m_impl, wxT("Socket not initialised") );
1940 
1941     return setsockopt(m_impl->m_fd, level, optname,
1942                       static_cast<const char *>(optval), optlen) == 0;
1943 }
1944 
SetLocal(const wxIPV4address & local)1945 bool wxSocketBase::SetLocal(const wxIPV4address& local)
1946 {
1947     m_localAddress = local;
1948 
1949     return true;
1950 }
1951 
1952 // ==========================================================================
1953 // wxSocketClient
1954 // ==========================================================================
1955 
1956 // --------------------------------------------------------------------------
1957 // Ctor and dtor
1958 // --------------------------------------------------------------------------
1959 
wxSocketClient(wxSocketFlags flags)1960 wxSocketClient::wxSocketClient(wxSocketFlags flags)
1961               : wxSocketBase(flags, wxSOCKET_CLIENT)
1962 {
1963     m_initialRecvBufferSize =
1964     m_initialSendBufferSize = -1;
1965 }
1966 
1967 // --------------------------------------------------------------------------
1968 // Connect
1969 // --------------------------------------------------------------------------
1970 
DoConnect(const wxSockAddress & remote,const wxSockAddress * local,bool wait)1971 bool wxSocketClient::DoConnect(const wxSockAddress& remote,
1972                                const wxSockAddress* local,
1973                                bool wait)
1974 {
1975     if ( m_impl )
1976     {
1977         // Shutdown and destroy the old socket
1978         Close();
1979         delete m_impl;
1980     }
1981 
1982     m_connected = false;
1983     m_establishing = false;
1984 
1985     // Create and set up the new one
1986     wxSocketManager * const manager = wxSocketManager::Get();
1987     m_impl = manager ? manager->CreateSocket(*this) : NULL;
1988     if ( !m_impl )
1989         return false;
1990 
1991     // Reuse makes sense for clients too, if we are trying to rebind to the same port
1992     if (GetFlags() & wxSOCKET_REUSEADDR)
1993         m_impl->SetReusable();
1994     if (GetFlags() & wxSOCKET_BROADCAST)
1995         m_impl->SetBroadcast();
1996     if (GetFlags() & wxSOCKET_NOBIND)
1997         m_impl->DontDoBind();
1998 
1999     // Bind to the local IP address and port, when provided or if one had been
2000     // set before
2001     if ( !local && m_localAddress.GetAddress().IsOk() )
2002         local = &m_localAddress;
2003 
2004     if ( local )
2005         m_impl->SetLocal(local->GetAddress());
2006 
2007     m_impl->SetInitialSocketBuffers(m_initialRecvBufferSize, m_initialSendBufferSize);
2008 
2009     m_impl->SetPeer(remote.GetAddress());
2010 
2011     // Finally do create the socket and connect to the peer
2012     const wxSocketError err = m_impl->CreateClient(wait);
2013 
2014     if ( err != wxSOCKET_NOERROR )
2015     {
2016         if ( err == wxSOCKET_WOULDBLOCK )
2017         {
2018             wxASSERT_MSG( !wait, "shouldn't get this for blocking connect" );
2019 
2020             m_establishing = true;
2021         }
2022 
2023         return false;
2024     }
2025 
2026     m_connected = true;
2027     return true;
2028 }
2029 
Connect(const wxSockAddress & remote,bool wait)2030 bool wxSocketClient::Connect(const wxSockAddress& remote, bool wait)
2031 {
2032     return DoConnect(remote, NULL, wait);
2033 }
2034 
Connect(const wxSockAddress & remote,const wxSockAddress & local,bool wait)2035 bool wxSocketClient::Connect(const wxSockAddress& remote,
2036                              const wxSockAddress& local,
2037                              bool wait)
2038 {
2039     return DoConnect(remote, &local, wait);
2040 }
2041 
WaitOnConnect(long seconds,long milliseconds)2042 bool wxSocketClient::WaitOnConnect(long seconds, long milliseconds)
2043 {
2044     if ( m_connected )
2045     {
2046         // this happens if the initial attempt to connect succeeded without
2047         // blocking
2048         return true;
2049     }
2050 
2051     wxCHECK_MSG( m_establishing && m_impl, false,
2052                  "No connection establishment attempt in progress" );
2053 
2054     // notice that we return true even if DoWait() returned -1, i.e. if an
2055     // error occurred and connection was lost: this is intentional as we should
2056     // return false only if timeout expired without anything happening
2057     return DoWait(seconds, milliseconds, wxSOCKET_CONNECTION_FLAG) != 0;
2058 }
2059 
2060 // ==========================================================================
2061 // wxDatagramSocket
2062 // ==========================================================================
2063 
wxDatagramSocket(const wxSockAddress & addr,wxSocketFlags flags)2064 wxDatagramSocket::wxDatagramSocket( const wxSockAddress& addr,
2065                                     wxSocketFlags flags )
2066                 : wxSocketBase( flags, wxSOCKET_DATAGRAM )
2067 {
2068     // Create the socket
2069     wxSocketManager * const manager = wxSocketManager::Get();
2070     m_impl = manager ? manager->CreateSocket(*this) : NULL;
2071 
2072     if (!m_impl)
2073         return;
2074 
2075     // Setup the socket as non connection oriented
2076     m_impl->SetLocal(addr.GetAddress());
2077     if (flags & wxSOCKET_REUSEADDR)
2078     {
2079         m_impl->SetReusable();
2080     }
2081     if (GetFlags() & wxSOCKET_BROADCAST)
2082     {
2083         m_impl->SetBroadcast();
2084     }
2085     if (GetFlags() & wxSOCKET_NOBIND)
2086     {
2087         m_impl->DontDoBind();
2088     }
2089 
2090     if ( m_impl->CreateUDP() != wxSOCKET_NOERROR )
2091     {
2092         wxDELETE(m_impl);
2093         return;
2094     }
2095 
2096     // Initialize all stuff
2097     m_connected = false;
2098     m_establishing = false;
2099 }
2100 
RecvFrom(wxSockAddress & addr,void * buf,wxUint32 nBytes)2101 wxDatagramSocket& wxDatagramSocket::RecvFrom( wxSockAddress& addr,
2102                                               void* buf,
2103                                               wxUint32 nBytes )
2104 {
2105     Read(buf, nBytes);
2106     GetPeer(addr);
2107     return (*this);
2108 }
2109 
SendTo(const wxSockAddress & addr,const void * buf,wxUint32 nBytes)2110 wxDatagramSocket& wxDatagramSocket::SendTo( const wxSockAddress& addr,
2111                                             const void* buf,
2112                                             wxUint32 nBytes )
2113 {
2114     wxASSERT_MSG( m_impl, wxT("Socket not initialised") );
2115 
2116     m_impl->SetPeer(addr.GetAddress());
2117     Write(buf, nBytes);
2118     return (*this);
2119 }
2120 
2121 // ==========================================================================
2122 // wxSocketModule
2123 // ==========================================================================
2124 
2125 class wxSocketModule : public wxModule
2126 {
2127 public:
OnInit()2128     virtual bool OnInit()
2129     {
2130         // wxSocketBase will call Initialize() itself only if sockets are
2131         // really used, don't do it from here
2132         return true;
2133     }
2134 
OnExit()2135     virtual void OnExit()
2136     {
2137         if ( wxSocketBase::IsInitialized() )
2138             wxSocketBase::Shutdown();
2139     }
2140 
2141 private:
2142     DECLARE_DYNAMIC_CLASS(wxSocketModule)
2143 };
2144 
2145 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
2146 
2147 #if defined(wxUSE_SELECT_DISPATCHER) && wxUSE_SELECT_DISPATCHER
2148 // NOTE: we need to force linking against socketiohandler.cpp otherwise in
2149 //       static builds of wxWidgets the ManagerSetter::ManagerSetter ctor
2150 //       contained there wouldn't be ever called
2151 wxFORCE_LINK_MODULE( socketiohandler )
2152 #endif
2153 
2154 // same for ManagerSetter in the MSW file
2155 #ifdef __WINDOWS__
2156     wxFORCE_LINK_MODULE( mswsocket )
2157 #endif
2158 
2159 // and for OSXManagerSetter in the OS X one
2160 #ifdef __WXOSX__
2161     wxFORCE_LINK_MODULE( osxsocket )
2162 #endif
2163 
2164 #endif // wxUSE_SOCKETS
2165