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