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) 2000-1999, Guillermo Rodriguez Garcia
8 // RCS_ID:     $Id: socket.cpp 44662 2007-03-07 23:21:48Z VZ $
9 // License:    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 
41 #include "wx/sckaddr.h"
42 #include "wx/datetime.h"
43 
44 // DLL options compatibility check:
45 #include "wx/build.h"
46 WX_CHECK_BUILD_OPTIONS("wxNet")
47 
48 // --------------------------------------------------------------------------
49 // macros and constants
50 // --------------------------------------------------------------------------
51 
52 // discard buffer
53 #define MAX_DISCARD_SIZE (10 * 1024)
54 
55 // what to do within waits: we have 2 cases: from the main thread itself we
56 // have to call wxYield() to let the events (including the GUI events and the
57 // low-level (not wxWidgets) events from GSocket) be processed. From another
58 // thread it is enough to just call wxThread::Yield() which will give away the
59 // rest of our time slice: the explanation is that the events will be processed
60 // by the main thread anyhow, without calling wxYield(), but we don't want to
61 // eat the CPU time uselessly while sitting in the loop waiting for the data
62 #if wxUSE_THREADS
63     #define PROCESS_EVENTS()        \
64     {                               \
65         if ( wxThread::IsMain() )   \
66             wxYield();              \
67         else                        \
68             wxThread::Yield();      \
69     }
70 #else // !wxUSE_THREADS
71     #define PROCESS_EVENTS() wxYield()
72 #endif // wxUSE_THREADS/!wxUSE_THREADS
73 
74 #define wxTRACE_Socket _T("wxSocket")
75 
76 // --------------------------------------------------------------------------
77 // wxWin macros
78 // --------------------------------------------------------------------------
79 
80 IMPLEMENT_CLASS(wxSocketBase, wxObject)
81 IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
82 IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
83 IMPLEMENT_CLASS(wxDatagramSocket, wxSocketBase)
84 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
85 
86 // --------------------------------------------------------------------------
87 // private classes
88 // --------------------------------------------------------------------------
89 
90 class wxSocketState : public wxObject
91 {
92 public:
93   wxSocketFlags            m_flags;
94   wxSocketEventFlags       m_eventmask;
95   bool                     m_notify;
96   void                    *m_clientData;
97 
98 public:
wxSocketState()99   wxSocketState() : wxObject() {}
100 
101   DECLARE_NO_COPY_CLASS(wxSocketState)
102 };
103 
104 // ==========================================================================
105 // wxSocketBase
106 // ==========================================================================
107 
108 // --------------------------------------------------------------------------
109 // Initialization and shutdown
110 // --------------------------------------------------------------------------
111 
112 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
113 //           to m_countInit with a crit section
114 size_t wxSocketBase::m_countInit = 0;
115 
IsInitialized()116 bool wxSocketBase::IsInitialized()
117 {
118     return m_countInit > 0;
119 }
120 
Initialize()121 bool wxSocketBase::Initialize()
122 {
123     if ( !m_countInit++ )
124     {
125         /*
126             Details: Initialize() creates a hidden window as a sink for socket
127             events, such as 'read completed'. wxMSW has only one message loop
128             for the main thread. If Initialize is called in a secondary thread,
129             the socket window will be created for the secondary thread, but
130             since there is no message loop on this thread, it will never
131             receive events and all socket operations will time out.
132             BTW, the main thread must not be stopped using sleep or block
133             on a semaphore (a bad idea in any case) or socket operations
134             will time out.
135 
136             On the Mac side, Initialize() stores a pointer to the CFRunLoop for
137             the main thread. Because secondary threads do not have run loops,
138             adding event notifications to the "Current" loop would have no
139             effect at all, events would never fire.
140         */
141         wxASSERT_MSG( wxIsMainThread(),
142             wxT("Call wxSocketBase::Initialize() from the main thread first!"));
143 
144         wxAppTraits *traits = wxAppConsole::GetInstance() ?
145                               wxAppConsole::GetInstance()->GetTraits() : NULL;
146         GSocketGUIFunctionsTable *functions =
147             traits ? traits->GetSocketGUIFunctionsTable() : NULL;
148         GSocket_SetGUIFunctions(functions);
149 
150         if ( !GSocket_Init() )
151         {
152             m_countInit--;
153 
154             return false;
155         }
156     }
157 
158     return true;
159 }
160 
Shutdown()161 void wxSocketBase::Shutdown()
162 {
163     // we should be initialized
164     wxASSERT_MSG( m_countInit, _T("extra call to Shutdown()") );
165     if ( --m_countInit == 0 )
166     {
167         GSocket_Cleanup();
168     }
169 }
170 
171 // --------------------------------------------------------------------------
172 // Ctor and dtor
173 // --------------------------------------------------------------------------
174 
Init()175 void wxSocketBase::Init()
176 {
177   m_socket       = NULL;
178   m_type         = wxSOCKET_UNINIT;
179 
180   // state
181   m_flags        = 0;
182   m_connected    =
183   m_establishing =
184   m_reading      =
185   m_writing      =
186   m_error        = false;
187   m_lcount       = 0;
188   m_timeout      = 600;
189   m_beingDeleted = false;
190 
191   // pushback buffer
192   m_unread       = NULL;
193   m_unrd_size    = 0;
194   m_unrd_cur     = 0;
195 
196   // events
197   m_id           = wxID_ANY;
198   m_handler      = NULL;
199   m_clientData   = NULL;
200   m_notify       = false;
201   m_eventmask    = 0;
202 
203   if ( !IsInitialized() )
204   {
205       // this Initialize() will be undone by wxSocketModule::OnExit(), all the
206       // other calls to it should be matched by a call to Shutdown()
207       Initialize();
208   }
209 }
210 
wxSocketBase()211 wxSocketBase::wxSocketBase()
212 {
213   Init();
214 }
215 
wxSocketBase(wxSocketFlags flags,wxSocketType type)216 wxSocketBase::wxSocketBase(wxSocketFlags flags, wxSocketType type)
217 {
218   Init();
219 
220   m_flags = flags;
221   m_type  = type;
222 }
223 
~wxSocketBase()224 wxSocketBase::~wxSocketBase()
225 {
226   // Just in case the app called Destroy() *and* then deleted
227   // the socket immediately: don't leave dangling pointers.
228   wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
229   if ( traits )
230       traits->RemoveFromPendingDelete(this);
231 
232   // Shutdown and close the socket
233   if (!m_beingDeleted)
234     Close();
235 
236   // Destroy the GSocket object
237   if (m_socket)
238     delete m_socket;
239 
240   // Free the pushback buffer
241   if (m_unread)
242     free(m_unread);
243 }
244 
Destroy()245 bool wxSocketBase::Destroy()
246 {
247   // Delayed destruction: the socket will be deleted during the next
248   // idle loop iteration. This ensures that all pending events have
249   // been processed.
250   m_beingDeleted = true;
251 
252   // Shutdown and close the socket
253   Close();
254 
255   // Supress events from now on
256   Notify(false);
257 
258   // schedule this object for deletion
259   wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
260   if ( traits )
261   {
262       // let the traits object decide what to do with us
263       traits->ScheduleForDestroy(this);
264   }
265   else // no app or no traits
266   {
267       // in wxBase we might have no app object at all, don't leak memory
268       delete this;
269   }
270 
271   return true;
272 }
273 
274 // --------------------------------------------------------------------------
275 // Basic IO calls
276 // --------------------------------------------------------------------------
277 
278 // The following IO operations update m_error and m_lcount:
279 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
280 //
281 // TODO: Should Connect, Accept and AcceptWith update m_error?
282 
Close()283 bool wxSocketBase::Close()
284 {
285   // Interrupt pending waits
286   InterruptWait();
287 
288   if (m_socket)
289   {
290     // Disable callbacks
291     m_socket->UnsetCallback(GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
292                                     GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG);
293 
294     // Shutdown the connection
295     m_socket->Shutdown();
296   }
297 
298   m_connected = false;
299   m_establishing = false;
300   return true;
301 }
302 
Read(void * buffer,wxUint32 nbytes)303 wxSocketBase& wxSocketBase::Read(void* buffer, wxUint32 nbytes)
304 {
305   // Mask read events
306   m_reading = true;
307 
308   m_lcount = _Read(buffer, nbytes);
309 
310   // If in wxSOCKET_WAITALL mode, all bytes should have been read.
311   if (m_flags & wxSOCKET_WAITALL)
312     m_error = (m_lcount != nbytes);
313   else
314     m_error = (m_lcount == 0);
315 
316   // Allow read events from now on
317   m_reading = false;
318 
319   return *this;
320 }
321 
_Read(void * buffer,wxUint32 nbytes)322 wxUint32 wxSocketBase::_Read(void* buffer, wxUint32 nbytes)
323 {
324   int total;
325 
326   // Try the pushback buffer first
327   total = GetPushback(buffer, nbytes, false);
328   nbytes -= total;
329   buffer  = (char *)buffer + total;
330 
331   // Return now in one of the following cases:
332   // - the socket is invalid,
333   // - we got all the data
334   if ( !m_socket ||
335        !nbytes )
336     return total;
337 
338   // Possible combinations (they are checked in this order)
339   // wxSOCKET_NOWAIT
340   // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
341   // wxSOCKET_BLOCK
342   // wxSOCKET_NONE
343   //
344   int ret;
345   if (m_flags & wxSOCKET_NOWAIT)
346   {
347     m_socket->SetNonBlocking(1);
348     ret = m_socket->Read((char *)buffer, nbytes);
349     m_socket->SetNonBlocking(0);
350 
351     if (ret > 0)
352       total += ret;
353   }
354   else
355   {
356     bool more = true;
357 
358     while (more)
359     {
360       if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForRead() )
361         break;
362 
363       ret = m_socket->Read((char *)buffer, nbytes);
364 
365       if (ret > 0)
366       {
367         total  += ret;
368         nbytes -= ret;
369         buffer  = (char *)buffer + ret;
370       }
371 
372       // If we got here and wxSOCKET_WAITALL is not set, we can leave
373       // now. Otherwise, wait until we recv all the data or until there
374       // is an error.
375       //
376       more = (ret > 0 && nbytes > 0 && (m_flags & wxSOCKET_WAITALL));
377     }
378   }
379 
380   return total;
381 }
382 
ReadMsg(void * buffer,wxUint32 nbytes)383 wxSocketBase& wxSocketBase::ReadMsg(void* buffer, wxUint32 nbytes)
384 {
385   wxUint32 len, len2, sig, total;
386   bool error;
387   int old_flags;
388   struct
389   {
390     unsigned char sig[4];
391     unsigned char len[4];
392   } msg;
393 
394   // Mask read events
395   m_reading = true;
396 
397   total = 0;
398   error = true;
399   old_flags = m_flags;
400   SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL);
401 
402   if (_Read(&msg, sizeof(msg)) != sizeof(msg))
403     goto exit;
404 
405   sig = (wxUint32)msg.sig[0];
406   sig |= (wxUint32)(msg.sig[1] << 8);
407   sig |= (wxUint32)(msg.sig[2] << 16);
408   sig |= (wxUint32)(msg.sig[3] << 24);
409 
410   if (sig != 0xfeeddead)
411   {
412     wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
413     goto exit;
414   }
415 
416   len = (wxUint32)msg.len[0];
417   len |= (wxUint32)(msg.len[1] << 8);
418   len |= (wxUint32)(msg.len[2] << 16);
419   len |= (wxUint32)(msg.len[3] << 24);
420 
421   if (len > nbytes)
422   {
423     len2 = len - nbytes;
424     len = nbytes;
425   }
426   else
427     len2 = 0;
428 
429   // Don't attemp to read if the msg was zero bytes long.
430   if (len)
431   {
432     total = _Read(buffer, len);
433 
434     if (total != len)
435       goto exit;
436   }
437   if (len2)
438   {
439     char *discard_buffer = new char[MAX_DISCARD_SIZE];
440     long discard_len;
441 
442     // NOTE: discarded bytes don't add to m_lcount.
443     do
444     {
445       discard_len = ((len2 > MAX_DISCARD_SIZE)? MAX_DISCARD_SIZE : len2);
446       discard_len = _Read(discard_buffer, (wxUint32)discard_len);
447       len2 -= (wxUint32)discard_len;
448     }
449     while ((discard_len > 0) && len2);
450 
451     delete [] discard_buffer;
452 
453     if (len2 != 0)
454       goto exit;
455   }
456   if (_Read(&msg, sizeof(msg)) != sizeof(msg))
457     goto exit;
458 
459   sig = (wxUint32)msg.sig[0];
460   sig |= (wxUint32)(msg.sig[1] << 8);
461   sig |= (wxUint32)(msg.sig[2] << 16);
462   sig |= (wxUint32)(msg.sig[3] << 24);
463 
464   if (sig != 0xdeadfeed)
465   {
466     wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
467     goto exit;
468   }
469 
470   // everything was OK
471   error = false;
472 
473 exit:
474   m_error = error;
475   m_lcount = total;
476   m_reading = false;
477   SetFlags(old_flags);
478 
479   return *this;
480 }
481 
Peek(void * buffer,wxUint32 nbytes)482 wxSocketBase& wxSocketBase::Peek(void* buffer, wxUint32 nbytes)
483 {
484   // Mask read events
485   m_reading = true;
486 
487   m_lcount = _Read(buffer, nbytes);
488   Pushback(buffer, m_lcount);
489 
490   // If in wxSOCKET_WAITALL mode, all bytes should have been read.
491   if (m_flags & wxSOCKET_WAITALL)
492     m_error = (m_lcount != nbytes);
493   else
494     m_error = (m_lcount == 0);
495 
496   // Allow read events again
497   m_reading = false;
498 
499   return *this;
500 }
501 
Write(const void * buffer,wxUint32 nbytes)502 wxSocketBase& wxSocketBase::Write(const void *buffer, wxUint32 nbytes)
503 {
504   // Mask write events
505   m_writing = true;
506 
507   m_lcount = _Write(buffer, nbytes);
508 
509   // If in wxSOCKET_WAITALL mode, all bytes should have been written.
510   if (m_flags & wxSOCKET_WAITALL)
511     m_error = (m_lcount != nbytes);
512   else
513     m_error = (m_lcount == 0);
514 
515   // Allow write events again
516   m_writing = false;
517 
518   return *this;
519 }
520 
_Write(const void * buffer,wxUint32 nbytes)521 wxUint32 wxSocketBase::_Write(const void *buffer, wxUint32 nbytes)
522 {
523   wxUint32 total = 0;
524 
525   // If the socket is invalid or parameters are ill, return immediately
526   if (!m_socket || !buffer || !nbytes)
527     return 0;
528 
529   // Possible combinations (they are checked in this order)
530   // wxSOCKET_NOWAIT
531   // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
532   // wxSOCKET_BLOCK
533   // wxSOCKET_NONE
534   //
535   int ret;
536   if (m_flags & wxSOCKET_NOWAIT)
537   {
538     m_socket->SetNonBlocking(1);
539     ret = m_socket->Write((const char *)buffer, nbytes);
540     m_socket->SetNonBlocking(0);
541 
542     if (ret > 0)
543       total = ret;
544   }
545   else
546   {
547     bool more = true;
548 
549     while (more)
550     {
551       if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForWrite() )
552         break;
553 
554       ret = m_socket->Write((const char *)buffer, nbytes);
555 
556       if (ret > 0)
557       {
558         total  += ret;
559         nbytes -= ret;
560         buffer  = (const char *)buffer + ret;
561       }
562 
563       // If we got here and wxSOCKET_WAITALL is not set, we can leave
564       // now. Otherwise, wait until we send all the data or until there
565       // is an error.
566       //
567       more = (ret > 0 && nbytes > 0 && (m_flags & wxSOCKET_WAITALL));
568     }
569   }
570 
571   return total;
572 }
573 
WriteMsg(const void * buffer,wxUint32 nbytes)574 wxSocketBase& wxSocketBase::WriteMsg(const void *buffer, wxUint32 nbytes)
575 {
576   wxUint32 total;
577   bool error;
578   struct
579   {
580     unsigned char sig[4];
581     unsigned char len[4];
582   } msg;
583 
584   // Mask write events
585   m_writing = true;
586 
587   error = true;
588   total = 0;
589   SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL);
590 
591   msg.sig[0] = (unsigned char) 0xad;
592   msg.sig[1] = (unsigned char) 0xde;
593   msg.sig[2] = (unsigned char) 0xed;
594   msg.sig[3] = (unsigned char) 0xfe;
595 
596   msg.len[0] = (unsigned char) (nbytes & 0xff);
597   msg.len[1] = (unsigned char) ((nbytes >> 8) & 0xff);
598   msg.len[2] = (unsigned char) ((nbytes >> 16) & 0xff);
599   msg.len[3] = (unsigned char) ((nbytes >> 24) & 0xff);
600 
601   if (_Write(&msg, sizeof(msg)) < sizeof(msg))
602     goto exit;
603 
604   total = _Write(buffer, nbytes);
605 
606   if (total < nbytes)
607     goto exit;
608 
609   msg.sig[0] = (unsigned char) 0xed;
610   msg.sig[1] = (unsigned char) 0xfe;
611   msg.sig[2] = (unsigned char) 0xad;
612   msg.sig[3] = (unsigned char) 0xde;
613   msg.len[0] = msg.len[1] = msg.len[2] = msg.len[3] = (char) 0;
614 
615   if ((_Write(&msg, sizeof(msg))) < sizeof(msg))
616     goto exit;
617 
618   // everything was OK
619   error = false;
620 
621 exit:
622   m_error = error;
623   m_lcount = total;
624   m_writing = false;
625 
626   return *this;
627 }
628 
Unread(const void * buffer,wxUint32 nbytes)629 wxSocketBase& wxSocketBase::Unread(const void *buffer, wxUint32 nbytes)
630 {
631   if (nbytes != 0)
632     Pushback(buffer, nbytes);
633 
634   m_error = false;
635   m_lcount = nbytes;
636 
637   return *this;
638 }
639 
Discard()640 wxSocketBase& wxSocketBase::Discard()
641 {
642   char *buffer = new char[MAX_DISCARD_SIZE];
643   wxUint32 ret;
644   wxUint32 total = 0;
645 
646   // Mask read events
647   m_reading = true;
648 
649   SetFlags(wxSOCKET_NOWAIT);
650 
651   do
652   {
653     ret = _Read(buffer, MAX_DISCARD_SIZE);
654     total += ret;
655   }
656   while (ret == MAX_DISCARD_SIZE);
657 
658   delete[] buffer;
659   m_lcount = total;
660   m_error  = false;
661 
662   // Allow read events again
663   m_reading = false;
664 
665   return *this;
666 }
667 
668 // --------------------------------------------------------------------------
669 // Wait functions
670 // --------------------------------------------------------------------------
671 
672 // All Wait functions poll the socket using GSocket_Select() to
673 // check for the specified combination of conditions, until one
674 // of these conditions become true, an error occurs, or the
675 // timeout elapses. The polling loop calls PROCESS_EVENTS(), so
676 // this won't block the GUI.
677 
_Wait(long seconds,long milliseconds,wxSocketEventFlags flags)678 bool wxSocketBase::_Wait(long seconds,
679                          long milliseconds,
680                          wxSocketEventFlags flags)
681 {
682   GSocketEventFlags result;
683   long timeout;
684 
685   // Set this to true to interrupt ongoing waits
686   m_interrupt = false;
687 
688   // Check for valid socket
689   if (!m_socket)
690     return false;
691 
692   // Check for valid timeout value.
693   if (seconds != -1)
694     timeout = seconds * 1000 + milliseconds;
695   else
696     timeout = m_timeout * 1000;
697 
698   bool has_event_loop = wxTheApp->GetTraits() ? (wxTheApp->GetTraits()->GetSocketGUIFunctionsTable() ? true : false) : false;
699 
700   // Wait in an active polling loop.
701   //
702   // NOTE: We duplicate some of the code in OnRequest, but this doesn't
703   //   hurt. It has to be here because the (GSocket) event might arrive
704   //   a bit delayed, and it has to be in OnRequest as well because we
705   //   don't know whether the Wait functions are being used.
706   //
707   // Do this at least once (important if timeout == 0, when
708   // we are just polling). Also, if just polling, do not yield.
709 
710   wxDateTime current_time = wxDateTime::UNow();
711   unsigned int time_limit = (current_time.GetTicks() * 1000) + current_time.GetMillisecond() + timeout;
712   bool done = false;
713   bool valid_result = false;
714 
715   if (!has_event_loop)
716   {
717     // This is used to avoid a busy loop on wxBase - having a select
718     // timeout of 50 ms per iteration should be enough.
719     if (timeout > 50)
720       m_socket->SetTimeout(50);
721     else
722       m_socket->SetTimeout(timeout);
723   }
724 
725   while (!done)
726   {
727     result = m_socket->Select(flags | GSOCK_LOST_FLAG);
728 
729     // Incoming connection (server) or connection established (client)
730     if (result & GSOCK_CONNECTION_FLAG)
731     {
732       m_connected = true;
733       m_establishing = false;
734       valid_result = true;
735       break;
736     }
737 
738     // Data available or output buffer ready
739     if ((result & GSOCK_INPUT_FLAG) || (result & GSOCK_OUTPUT_FLAG))
740     {
741       valid_result = true;
742       break;
743     }
744 
745     // Connection lost
746     if (result & GSOCK_LOST_FLAG)
747     {
748       m_connected = false;
749       m_establishing = false;
750       valid_result = ((flags & GSOCK_LOST_FLAG) != 0);
751       break;
752     }
753 
754     // Wait more?
755     current_time = wxDateTime::UNow();
756     int time_left = time_limit - ((current_time.GetTicks() * 1000) + current_time.GetMillisecond());
757     if ((!timeout) || (time_left <= 0) || (m_interrupt))
758       done = true;
759     else
760     {
761       if (has_event_loop)
762       {
763           PROCESS_EVENTS();
764       }
765       else
766       {
767         // If there's less than 50 ms left, just call select with that timeout.
768         if (time_left < 50)
769           m_socket->SetTimeout(time_left);
770       }
771     }
772   }
773 
774   // Set timeout back to original value (we overwrote it for polling)
775   if (!has_event_loop)
776     m_socket->SetTimeout(m_timeout*1000);
777 
778   return valid_result;
779 }
780 
Wait(long seconds,long milliseconds)781 bool wxSocketBase::Wait(long seconds, long milliseconds)
782 {
783     return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG |
784                                         GSOCK_OUTPUT_FLAG |
785                                         GSOCK_CONNECTION_FLAG |
786                                         GSOCK_LOST_FLAG);
787 }
788 
WaitForRead(long seconds,long milliseconds)789 bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
790 {
791   // Check pushback buffer before entering _Wait
792   if (m_unread)
793     return true;
794 
795   // Note that GSOCK_INPUT_LOST has to be explicitly passed to
796   // _Wait because of the semantics of WaitForRead: a return
797   // value of true means that a GSocket_Read call will return
798   // immediately, not that there is actually data to read.
799 
800   return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG |
801                                       GSOCK_LOST_FLAG);
802 }
803 
804 
WaitForWrite(long seconds,long milliseconds)805 bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
806 {
807     return _Wait(seconds, milliseconds, GSOCK_OUTPUT_FLAG);
808 }
809 
WaitForLost(long seconds,long milliseconds)810 bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
811 {
812     return _Wait(seconds, milliseconds, GSOCK_LOST_FLAG);
813 }
814 
815 // --------------------------------------------------------------------------
816 // Miscellaneous
817 // --------------------------------------------------------------------------
818 
819 //
820 // Get local or peer address
821 //
822 
GetPeer(wxSockAddress & addr_man) const823 bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const
824 {
825   GAddress *peer;
826 
827   if (!m_socket)
828     return false;
829 
830   peer = m_socket->GetPeer();
831 
832     // copying a null address would just trigger an assert anyway
833 
834   if (!peer)
835     return false;
836 
837   addr_man.SetAddress(peer);
838   GAddress_destroy(peer);
839 
840   return true;
841 }
842 
GetLocal(wxSockAddress & addr_man) const843 bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const
844 {
845     GAddress *local;
846 
847     if (!m_socket)
848         return false;
849 
850     local = m_socket->GetLocal();
851     addr_man.SetAddress(local);
852     GAddress_destroy(local);
853 
854     return true;
855 }
856 
857 //
858 // Save and restore socket state
859 //
860 
SaveState()861 void wxSocketBase::SaveState()
862 {
863     wxSocketState *state;
864 
865     state = new wxSocketState();
866 
867     state->m_flags      = m_flags;
868     state->m_notify     = m_notify;
869     state->m_eventmask  = m_eventmask;
870     state->m_clientData = m_clientData;
871 
872     m_states.Append(state);
873 }
874 
RestoreState()875 void wxSocketBase::RestoreState()
876 {
877     wxList::compatibility_iterator node;
878     wxSocketState *state;
879 
880     node = m_states.GetLast();
881     if (!node)
882         return;
883 
884     state = (wxSocketState *)node->GetData();
885 
886     m_flags      = state->m_flags;
887     m_notify     = state->m_notify;
888     m_eventmask  = state->m_eventmask;
889     m_clientData = state->m_clientData;
890 
891     m_states.Erase(node);
892     delete state;
893 }
894 
895 //
896 // Timeout and flags
897 //
898 
SetTimeout(long seconds)899 void wxSocketBase::SetTimeout(long seconds)
900 {
901     m_timeout = seconds;
902 
903     if (m_socket)
904         m_socket->SetTimeout(m_timeout * 1000);
905 }
906 
SetFlags(wxSocketFlags flags)907 void wxSocketBase::SetFlags(wxSocketFlags flags)
908 {
909     m_flags = flags;
910 }
911 
912 
913 // --------------------------------------------------------------------------
914 // Event handling
915 // --------------------------------------------------------------------------
916 
917 // A note on how events are processed, which is probably the most
918 // difficult thing to get working right while keeping the same API
919 // and functionality for all platforms.
920 //
921 // When GSocket detects an event, it calls wx_socket_callback, which in
922 // turn just calls wxSocketBase::OnRequest in the corresponding wxSocket
923 // object. OnRequest does some housekeeping, and if the event is to be
924 // propagated to the user, it creates a new wxSocketEvent object and
925 // posts it. The event is not processed immediately, but delayed with
926 // AddPendingEvent instead. This is necessary in order to decouple the
927 // event processing from wx_socket_callback; otherwise, subsequent IO
928 // calls made from the user event handler would fail, as gtk callbacks
929 // are not reentrant.
930 //
931 // Note that, unlike events, user callbacks (now deprecated) are _not_
932 // decoupled from wx_socket_callback and thus they suffer from a variety
933 // of problems. Avoid them where possible and use events instead.
934 
935 extern "C"
wx_socket_callback(GSocket * WXUNUSED (socket),GSocketEvent notification,char * cdata)936 void LINKAGEMODE wx_socket_callback(GSocket * WXUNUSED(socket),
937                                     GSocketEvent notification,
938                                     char *cdata)
939 {
940     wxSocketBase *sckobj = (wxSocketBase *)cdata;
941 
942     sckobj->OnRequest((wxSocketNotify) notification);
943 }
944 
OnRequest(wxSocketNotify notification)945 void wxSocketBase::OnRequest(wxSocketNotify notification)
946 {
947   // NOTE: We duplicate some of the code in _Wait, but this doesn't
948   //   hurt. It has to be here because the (GSocket) event might arrive
949   //   a bit delayed, and it has to be in _Wait as well because we don't
950   //   know whether the Wait functions are being used.
951 
952   switch(notification)
953   {
954     case wxSOCKET_CONNECTION:
955       m_establishing = false;
956       m_connected = true;
957       break;
958 
959     // If we are in the middle of a R/W operation, do not
960     // propagate events to users. Also, filter 'late' events
961     // which are no longer valid.
962 
963     case wxSOCKET_INPUT:
964       if (m_reading || !m_socket->Select(GSOCK_INPUT_FLAG))
965         return;
966       break;
967 
968     case wxSOCKET_OUTPUT:
969       if (m_writing || !m_socket->Select(GSOCK_OUTPUT_FLAG))
970         return;
971       break;
972 
973     case wxSOCKET_LOST:
974       m_connected = false;
975       m_establishing = false;
976       break;
977 
978     default:
979       break;
980   }
981 
982   // Schedule the event
983 
984   wxSocketEventFlags flag = 0;
985   wxUnusedVar(flag);
986   switch (notification)
987   {
988     case GSOCK_INPUT:      flag = GSOCK_INPUT_FLAG; break;
989     case GSOCK_OUTPUT:     flag = GSOCK_OUTPUT_FLAG; break;
990     case GSOCK_CONNECTION: flag = GSOCK_CONNECTION_FLAG; break;
991     case GSOCK_LOST:       flag = GSOCK_LOST_FLAG; break;
992     default:
993       wxLogWarning(_("wxSocket: unknown event!."));
994       return;
995   }
996 
997   if (((m_eventmask & flag) == flag) && m_notify)
998   {
999     if (m_handler)
1000     {
1001       wxSocketEvent event(m_id);
1002       event.m_event      = notification;
1003       event.m_clientData = m_clientData;
1004       event.SetEventObject(this);
1005 
1006       m_handler->AddPendingEvent(event);
1007     }
1008   }
1009 }
1010 
Notify(bool notify)1011 void wxSocketBase::Notify(bool notify)
1012 {
1013     m_notify = notify;
1014 }
1015 
SetNotify(wxSocketEventFlags flags)1016 void wxSocketBase::SetNotify(wxSocketEventFlags flags)
1017 {
1018     m_eventmask = flags;
1019 }
1020 
SetEventHandler(wxEvtHandler & handler,int id)1021 void wxSocketBase::SetEventHandler(wxEvtHandler& handler, int id)
1022 {
1023     m_handler = &handler;
1024     m_id      = id;
1025 }
1026 
1027 // --------------------------------------------------------------------------
1028 // Pushback buffer
1029 // --------------------------------------------------------------------------
1030 
Pushback(const void * buffer,wxUint32 size)1031 void wxSocketBase::Pushback(const void *buffer, wxUint32 size)
1032 {
1033   if (!size) return;
1034 
1035   if (m_unread == NULL)
1036     m_unread = malloc(size);
1037   else
1038   {
1039     void *tmp;
1040 
1041     tmp = malloc(m_unrd_size + size);
1042     memcpy((char *)tmp + size, m_unread, m_unrd_size);
1043     free(m_unread);
1044 
1045     m_unread = tmp;
1046   }
1047 
1048   m_unrd_size += size;
1049 
1050   memcpy(m_unread, buffer, size);
1051 }
1052 
GetPushback(void * buffer,wxUint32 size,bool peek)1053 wxUint32 wxSocketBase::GetPushback(void *buffer, wxUint32 size, bool peek)
1054 {
1055   if (!m_unrd_size)
1056     return 0;
1057 
1058   if (size > (m_unrd_size-m_unrd_cur))
1059     size = m_unrd_size-m_unrd_cur;
1060 
1061   memcpy(buffer, (char *)m_unread + m_unrd_cur, size);
1062 
1063   if (!peek)
1064   {
1065     m_unrd_cur += size;
1066     if (m_unrd_size == m_unrd_cur)
1067     {
1068       free(m_unread);
1069       m_unread = NULL;
1070       m_unrd_size = 0;
1071       m_unrd_cur  = 0;
1072     }
1073   }
1074 
1075   return size;
1076 }
1077 
1078 
1079 // ==========================================================================
1080 // wxSocketServer
1081 // ==========================================================================
1082 
1083 // --------------------------------------------------------------------------
1084 // Ctor
1085 // --------------------------------------------------------------------------
1086 
wxSocketServer(const wxSockAddress & addr_man,wxSocketFlags flags)1087 wxSocketServer::wxSocketServer(const wxSockAddress& addr_man,
1088                                wxSocketFlags flags)
1089               : wxSocketBase(flags, wxSOCKET_SERVER)
1090 {
1091     wxLogTrace( wxTRACE_Socket, _T("Opening wxSocketServer") );
1092 
1093     m_socket = GSocket_new();
1094 
1095     if (!m_socket)
1096     {
1097         wxLogTrace( wxTRACE_Socket, _T("*** GSocket_new failed") );
1098         return;
1099     }
1100 
1101         // Setup the socket as server
1102 
1103     m_socket->SetLocal(addr_man.GetAddress());
1104 
1105     if (GetFlags() & wxSOCKET_REUSEADDR) {
1106         m_socket->SetReusable();
1107     }
1108 
1109     if (m_socket->SetServer() != GSOCK_NOERROR)
1110     {
1111         delete m_socket;
1112         m_socket = NULL;
1113 
1114         wxLogTrace( wxTRACE_Socket, _T("*** GSocket_SetServer failed") );
1115         return;
1116     }
1117 
1118     m_socket->SetTimeout(m_timeout * 1000);
1119     m_socket->SetCallback(GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1120                                   GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1121                                   wx_socket_callback, (char *)this);
1122 }
1123 
1124 // --------------------------------------------------------------------------
1125 // Accept
1126 // --------------------------------------------------------------------------
1127 
AcceptWith(wxSocketBase & sock,bool wait)1128 bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait)
1129 {
1130   GSocket *child_socket;
1131 
1132   if (!m_socket)
1133     return false;
1134 
1135   // If wait == false, then the call should be nonblocking.
1136   // When we are finished, we put the socket to blocking mode
1137   // again.
1138 
1139   if (!wait)
1140     m_socket->SetNonBlocking(1);
1141 
1142   child_socket = m_socket->WaitConnection();
1143 
1144   if (!wait)
1145     m_socket->SetNonBlocking(0);
1146 
1147   if (!child_socket)
1148     return false;
1149 
1150   sock.m_type = wxSOCKET_BASE;
1151   sock.m_socket = child_socket;
1152   sock.m_connected = true;
1153 
1154   sock.m_socket->SetTimeout(sock.m_timeout * 1000);
1155   sock.m_socket->SetCallback(GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1156                                      GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1157                                      wx_socket_callback, (char *)&sock);
1158 
1159   return true;
1160 }
1161 
Accept(bool wait)1162 wxSocketBase *wxSocketServer::Accept(bool wait)
1163 {
1164   wxSocketBase* sock = new wxSocketBase();
1165 
1166   sock->SetFlags(m_flags);
1167 
1168   if (!AcceptWith(*sock, wait))
1169   {
1170     sock->Destroy();
1171     sock = NULL;
1172   }
1173 
1174   return sock;
1175 }
1176 
WaitForAccept(long seconds,long milliseconds)1177 bool wxSocketServer::WaitForAccept(long seconds, long milliseconds)
1178 {
1179     return _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG);
1180 }
1181 
GetOption(int level,int optname,void * optval,int * optlen)1182 bool wxSocketBase::GetOption(int level, int optname, void *optval, int *optlen)
1183 {
1184     wxASSERT_MSG( m_socket, _T("Socket not initialised") );
1185 
1186     if (m_socket->GetSockOpt(level, optname, optval, optlen)
1187         != GSOCK_NOERROR)
1188     {
1189         return false;
1190     }
1191     return true;
1192 }
1193 
SetOption(int level,int optname,const void * optval,int optlen)1194 bool wxSocketBase::SetOption(int level, int optname, const void *optval,
1195                               int optlen)
1196 {
1197     wxASSERT_MSG( m_socket, _T("Socket not initialised") );
1198 
1199     if (m_socket->SetSockOpt(level, optname, optval, optlen)
1200         != GSOCK_NOERROR)
1201     {
1202         return false;
1203     }
1204     return true;
1205 }
1206 
SetLocal(wxIPV4address & local)1207 bool wxSocketBase::SetLocal(wxIPV4address& local)
1208 {
1209   GAddress* la = local.GetAddress();
1210 
1211   // If the address is valid, save it for use when we call Connect
1212   if (la && la->m_addr)
1213   {
1214     m_localAddress = local;
1215 
1216     return true;
1217   }
1218 
1219   return false;
1220 }
1221 
1222 // ==========================================================================
1223 // wxSocketClient
1224 // ==========================================================================
1225 
1226 // --------------------------------------------------------------------------
1227 // Ctor and dtor
1228 // --------------------------------------------------------------------------
1229 
wxSocketClient(wxSocketFlags flags)1230 wxSocketClient::wxSocketClient(wxSocketFlags flags)
1231               : wxSocketBase(flags, wxSOCKET_CLIENT)
1232 {
1233 }
1234 
~wxSocketClient()1235 wxSocketClient::~wxSocketClient()
1236 {
1237 }
1238 
1239 // --------------------------------------------------------------------------
1240 // Connect
1241 // --------------------------------------------------------------------------
1242 
DoConnect(wxSockAddress & addr_man,wxSockAddress * local,bool wait)1243 bool wxSocketClient::DoConnect(wxSockAddress& addr_man, wxSockAddress* local, bool wait)
1244 {
1245   GSocketError err;
1246 
1247   if (m_socket)
1248   {
1249     // Shutdown and destroy the socket
1250     Close();
1251     delete m_socket;
1252   }
1253 
1254   m_socket = GSocket_new();
1255   m_connected = false;
1256   m_establishing = false;
1257 
1258   if (!m_socket)
1259     return false;
1260 
1261   m_socket->SetTimeout(m_timeout * 1000);
1262   m_socket->SetCallback(GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1263                                 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1264                                 wx_socket_callback, (char *)this);
1265 
1266   // If wait == false, then the call should be nonblocking.
1267   // When we are finished, we put the socket to blocking mode
1268   // again.
1269 
1270   if (!wait)
1271     m_socket->SetNonBlocking(1);
1272 
1273   // Reuse makes sense for clients too, if we are trying to rebind to the same port
1274   if (GetFlags() & wxSOCKET_REUSEADDR)
1275   {
1276     m_socket->SetReusable();
1277   }
1278 
1279   // If no local address was passed and one has been set, use the one that was Set
1280   if (!local && m_localAddress.GetAddress())
1281   {
1282     local = &m_localAddress;
1283   }
1284 
1285   // Bind to the local IP address and port, when provided
1286   if (local)
1287   {
1288     GAddress* la = local->GetAddress();
1289 
1290     if (la && la->m_addr)
1291       m_socket->SetLocal(la);
1292   }
1293 
1294   m_socket->SetPeer(addr_man.GetAddress());
1295   err = m_socket->Connect(GSOCK_STREAMED);
1296 
1297   if (!wait)
1298     m_socket->SetNonBlocking(0);
1299 
1300   if (err != GSOCK_NOERROR)
1301   {
1302     if (err == GSOCK_WOULDBLOCK)
1303       m_establishing = true;
1304 
1305     return false;
1306   }
1307 
1308   m_connected = true;
1309   return true;
1310 }
1311 
Connect(wxSockAddress & addr_man,bool wait)1312 bool wxSocketClient::Connect(wxSockAddress& addr_man, bool wait)
1313 {
1314     return (DoConnect(addr_man, NULL, wait));
1315 }
1316 
Connect(wxSockAddress & addr_man,wxSockAddress & local,bool wait)1317 bool wxSocketClient::Connect(wxSockAddress& addr_man, wxSockAddress& local, bool wait)
1318 {
1319     return (DoConnect(addr_man, &local, wait));
1320 }
1321 
WaitOnConnect(long seconds,long milliseconds)1322 bool wxSocketClient::WaitOnConnect(long seconds, long milliseconds)
1323 {
1324     if (m_connected)                      // Already connected
1325         return true;
1326 
1327     if (!m_establishing || !m_socket)     // No connection in progress
1328         return false;
1329 
1330     return _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG |
1331                                         GSOCK_LOST_FLAG);
1332 }
1333 
1334 // ==========================================================================
1335 // wxDatagramSocket
1336 // ==========================================================================
1337 
1338 /* NOTE: experimental stuff - might change */
1339 
wxDatagramSocket(const wxSockAddress & addr,wxSocketFlags flags)1340 wxDatagramSocket::wxDatagramSocket( const wxSockAddress& addr,
1341                                     wxSocketFlags flags )
1342                 : wxSocketBase( flags, wxSOCKET_DATAGRAM )
1343 {
1344     // Create the socket
1345     m_socket = GSocket_new();
1346 
1347     if (!m_socket)
1348     {
1349         wxFAIL_MSG( _T("datagram socket not new'd") );
1350         return;
1351     }
1352     // Setup the socket as non connection oriented
1353     m_socket->SetLocal(addr.GetAddress());
1354     if (flags & wxSOCKET_REUSEADDR)
1355     {
1356         m_socket->SetReusable();
1357     }
1358     if ( m_socket->SetNonOriented() != GSOCK_NOERROR )
1359     {
1360         delete m_socket;
1361         m_socket = NULL;
1362         return;
1363     }
1364 
1365     // Initialize all stuff
1366     m_connected = false;
1367     m_establishing = false;
1368     m_socket->SetTimeout( m_timeout );
1369     m_socket->SetCallback( GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1370                            GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1371                            wx_socket_callback, (char*)this );
1372 }
1373 
RecvFrom(wxSockAddress & addr,void * buf,wxUint32 nBytes)1374 wxDatagramSocket& wxDatagramSocket::RecvFrom( wxSockAddress& addr,
1375                                               void* buf,
1376                                               wxUint32 nBytes )
1377 {
1378     Read(buf, nBytes);
1379     GetPeer(addr);
1380     return (*this);
1381 }
1382 
SendTo(const wxSockAddress & addr,const void * buf,wxUint32 nBytes)1383 wxDatagramSocket& wxDatagramSocket::SendTo( const wxSockAddress& addr,
1384                                             const void* buf,
1385                                             wxUint32 nBytes )
1386 {
1387     wxASSERT_MSG( m_socket, _T("Socket not initialised") );
1388 
1389     m_socket->SetPeer(addr.GetAddress());
1390     Write(buf, nBytes);
1391     return (*this);
1392 }
1393 
1394 // ==========================================================================
1395 // wxSocketModule
1396 // ==========================================================================
1397 
1398 class wxSocketModule : public wxModule
1399 {
1400 public:
OnInit()1401     virtual bool OnInit()
1402     {
1403         // wxSocketBase will call GSocket_Init() itself when/if needed
1404         return true;
1405     }
1406 
OnExit()1407     virtual void OnExit()
1408     {
1409         if ( wxSocketBase::IsInitialized() )
1410             wxSocketBase::Shutdown();
1411     }
1412 
1413 private:
1414     DECLARE_DYNAMIC_CLASS(wxSocketModule)
1415 };
1416 
1417 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
1418 
1419 #endif
1420   // wxUSE_SOCKETS
1421