use wxCriticalSection instead of CRITICAL_SECTION and, more importantly, wxCSLocker...
[wxWidgets.git] / src / msw / sockmsw.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/sockmsw.cpp
3 // Purpose: MSW-specific socket code
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 // RCS_ID: $Id$
10 // License: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
12
13
14 // For compilers that support precompilation, includes "wx.h".
15 #include "wx/wxprec.h"
16
17 #ifdef __BORLANDC__
18 #pragma hdrstop
19 #endif
20
21 #if wxUSE_SOCKETS
22
23 /* including rasasync.h (included from windows.h itself included from
24 * wx/setup.h and/or winsock.h results in this warning for
25 * RPCNOTIFICATION_ROUTINE
26 */
27 #ifdef _MSC_VER
28 # pragma warning(disable:4115) /* named type definition in parentheses */
29 #endif
30
31 #include "wx/private/socket.h"
32 #include "wx/apptrait.h"
33 #include "wx/thread.h"
34
35 extern "C" WXDLLIMPEXP_BASE HINSTANCE wxGetInstance();
36 #define INSTANCE wxGetInstance()
37
38 #include <winsock.h>
39
40 #if defined(__CYGWIN__)
41 //CYGWIN gives annoying warning about runtime stuff if we don't do this
42 # define USE_SYS_TYPES_FD_SET
43 # include <sys/types.h>
44 #endif
45
46 #ifdef __WXWINCE__
47 /*
48 * As WSAAsyncSelect is not present on WinCE, it now uses WSACreateEvent,
49 * WSAEventSelect, WSAWaitForMultipleEvents and WSAEnumNetworkEvents. When
50 * enabling eventhandling for a socket a new thread it created that keeps track
51 * of the events and posts a messageto the hidden window to use the standard
52 * message loop.
53 */
54 #include "wx/msw/wince/net.h"
55 #include "wx/hashmap.h"
56 WX_DECLARE_HASH_MAP(int,bool,wxIntegerHash,wxIntegerEqual,SocketHash);
57
58 #ifndef isdigit
59 #define isdigit(x) (x > 47 && x < 58)
60 #endif
61 #include "wx/msw/wince/net.h"
62
63 #endif // __WXWINCE__
64
65 #ifdef _MSC_VER
66 # pragma warning(default:4115) /* named type definition in parentheses */
67 #endif
68
69 #define CLASSNAME TEXT("_wxSocket_Internal_Window_Class")
70
71 /* implemented in utils.cpp */
72 extern "C" WXDLLIMPEXP_BASE HWND
73 wxCreateHiddenWindow(LPCTSTR *pclassname, LPCTSTR classname, WNDPROC wndproc);
74
75 /* Maximum number of different wxSocket objects at a given time.
76 * This value can be modified at will, but it CANNOT be greater
77 * than (0x7FFF - WM_USER + 1)
78 */
79 #define MAXSOCKETS 1024
80
81 #if (MAXSOCKETS > (0x7FFF - WM_USER + 1))
82 #error "MAXSOCKETS is too big!"
83 #endif
84
85 #ifndef __WXWINCE__
86 typedef int (PASCAL *WSAAsyncSelectFunc)(SOCKET,HWND,u_int,long);
87 #else
88 /* Typedef the needed function prototypes and the WSANETWORKEVENTS structure
89 */
90 typedef struct _WSANETWORKEVENTS {
91 long lNetworkEvents;
92 int iErrorCode[10];
93 } WSANETWORKEVENTS, FAR * LPWSANETWORKEVENTS;
94 typedef HANDLE (PASCAL *WSACreateEventFunc)();
95 typedef int (PASCAL *WSAEventSelectFunc)(SOCKET,HANDLE,long);
96 typedef int (PASCAL *WSAWaitForMultipleEventsFunc)(long,HANDLE,BOOL,long,BOOL);
97 typedef int (PASCAL *WSAEnumNetworkEventsFunc)(SOCKET,HANDLE,LPWSANETWORKEVENTS);
98 #endif //__WXWINCE__
99
100 LRESULT CALLBACK wxSocket_Internal_WinProc(HWND, UINT, WPARAM, LPARAM);
101
102 /* Global variables */
103
104 static HWND hWin;
105 wxCRIT_SECT_DECLARE_MEMBER(gs_critical);
106 static wxSocketImplMSW *socketList[MAXSOCKETS];
107 static int firstAvailable;
108
109 #ifndef __WXWINCE__
110 static WSAAsyncSelectFunc gs_WSAAsyncSelect = NULL;
111 #else
112 static SocketHash socketHash;
113 static unsigned int currSocket;
114 HANDLE hThread[MAXSOCKETS];
115 static WSACreateEventFunc gs_WSACreateEvent = NULL;
116 static WSAEventSelectFunc gs_WSAEventSelect = NULL;
117 static WSAWaitForMultipleEventsFunc gs_WSAWaitForMultipleEvents = NULL;
118 static WSAEnumNetworkEventsFunc gs_WSAEnumNetworkEvents = NULL;
119 /* This structure will be used to pass data on to the thread that handles socket events.
120 */
121 typedef struct thread_data{
122 HWND hEvtWin;
123 unsigned long msgnumber;
124 unsigned long fd;
125 unsigned long lEvent;
126 }thread_data;
127 #endif
128
129 static HMODULE gs_wsock32dll = 0;
130
131
132 #ifdef __WXWINCE__
133 /* This thread handles socket events on WinCE using WSAEventSelect() as WSAAsyncSelect is not supported.
134 * When an event occures for the socket, it is checked what kind of event happend and the correct message gets posted
135 * so that the hidden window can handle it as it would in other MSW builds.
136 */
137 DWORD WINAPI SocketThread(LPVOID data)
138 {
139 WSANETWORKEVENTS NetworkEvents;
140 thread_data* d = (thread_data *)data;
141
142 HANDLE NetworkEvent = gs_WSACreateEvent();
143 gs_WSAEventSelect(d->fd, NetworkEvent, d->lEvent);
144
145 while(socketHash[d->fd] == true)
146 {
147 if ((gs_WSAWaitForMultipleEvents(1, &NetworkEvent, FALSE,INFINITE, FALSE)) == WAIT_FAILED)
148 {
149 printf("WSAWaitForMultipleEvents failed with error %d\n", WSAGetLastError());
150 return 0;
151 }
152 if (gs_WSAEnumNetworkEvents(d->fd ,NetworkEvent, &NetworkEvents) == SOCKET_ERROR)
153 {
154 printf("WSAEnumNetworkEvents failed with error %d\n", WSAGetLastError());
155 return 0;
156 }
157
158 long flags = NetworkEvents.lNetworkEvents;
159 if (flags & FD_READ)
160 ::PostMessage(d->hEvtWin, d->msgnumber,d->fd, FD_READ);
161 if (flags & FD_WRITE)
162 ::PostMessage(d->hEvtWin, d->msgnumber,d->fd, FD_WRITE);
163 if (flags & FD_OOB)
164 ::PostMessage(d->hEvtWin, d->msgnumber,d->fd, FD_OOB);
165 if (flags & FD_ACCEPT)
166 ::PostMessage(d->hEvtWin, d->msgnumber,d->fd, FD_ACCEPT);
167 if (flags & FD_CONNECT)
168 ::PostMessage(d->hEvtWin, d->msgnumber,d->fd, FD_CONNECT);
169 if (flags & FD_CLOSE)
170 ::PostMessage(d->hEvtWin, d->msgnumber,d->fd, FD_CLOSE);
171
172 }
173 gs_WSAEventSelect(d->fd, NetworkEvent, 0);
174 ExitThread(0);
175 return 0;
176 }
177 #endif
178
179 // ----------------------------------------------------------------------------
180 // MSW implementation of wxSocketManager
181 // ----------------------------------------------------------------------------
182
183 class wxSocketMSWManager : public wxSocketManager
184 {
185 public:
186 virtual bool OnInit();
187 virtual void OnExit();
188
189 virtual wxSocketImpl *CreateSocket(wxSocketBase& wxsocket)
190 {
191 return new wxSocketImplMSW(wxsocket);
192 }
193 virtual void Install_Callback(wxSocketImpl *socket, wxSocketNotify event);
194 virtual void Uninstall_Callback(wxSocketImpl *socket, wxSocketNotify event);
195 };
196
197 bool wxSocketMSWManager::OnInit()
198 {
199 static LPCTSTR pclassname = NULL;
200 int i;
201
202 /* Create internal window for event notifications */
203 hWin = wxCreateHiddenWindow(&pclassname, CLASSNAME, wxSocket_Internal_WinProc);
204 if (!hWin)
205 return false;
206
207 /* Initialize socket list */
208 for (i = 0; i < MAXSOCKETS; i++)
209 {
210 socketList[i] = NULL;
211 }
212 firstAvailable = 0;
213
214 /* Load WSAAsyncSelect from wsock32.dll (we don't link against it
215 statically to avoid dependency on wsock32.dll for apps that don't use
216 sockets): */
217 #ifndef __WXWINCE__
218 gs_wsock32dll = LoadLibrary(wxT("wsock32.dll"));
219 if (!gs_wsock32dll)
220 return false;
221 gs_WSAAsyncSelect =(WSAAsyncSelectFunc)GetProcAddress(gs_wsock32dll,
222 "WSAAsyncSelect");
223 if (!gs_WSAAsyncSelect)
224 return false;
225 #else
226 /* On WinCE we load ws2.dll which will provide the needed functions.
227 */
228 gs_wsock32dll = LoadLibrary(wxT("ws2.dll"));
229 if (!gs_wsock32dll)
230 return false;
231 gs_WSAEventSelect =(WSAEventSelectFunc)GetProcAddress(gs_wsock32dll,
232 wxT("WSAEventSelect"));
233 if (!gs_WSAEventSelect)
234 return false;
235
236 gs_WSACreateEvent =(WSACreateEventFunc)GetProcAddress(gs_wsock32dll,
237 wxT("WSACreateEvent"));
238 if (!gs_WSACreateEvent)
239 return false;
240
241 gs_WSAWaitForMultipleEvents =(WSAWaitForMultipleEventsFunc)GetProcAddress(gs_wsock32dll,
242 wxT("WSAWaitForMultipleEvents"));
243 if (!gs_WSAWaitForMultipleEvents)
244 return false;
245
246 gs_WSAEnumNetworkEvents =(WSAEnumNetworkEventsFunc)GetProcAddress(gs_wsock32dll,
247 wxT("WSAEnumNetworkEvents"));
248 if (!gs_WSAEnumNetworkEvents)
249 return false;
250
251 currSocket = 0;
252 #endif
253
254 // finally initialize WinSock
255 WSADATA wsaData;
256 return WSAStartup((1 << 8) | 1, &wsaData) == 0;
257 }
258
259 void wxSocketMSWManager::OnExit()
260 {
261 #ifdef __WXWINCE__
262 /* Delete the threads here */
263 for(unsigned int i=0; i < currSocket; i++)
264 CloseHandle(hThread[i]);
265 #endif
266 /* Destroy internal window */
267 DestroyWindow(hWin);
268 UnregisterClass(CLASSNAME, INSTANCE);
269
270 /* Unlock wsock32.dll */
271 if (gs_wsock32dll)
272 {
273 FreeLibrary(gs_wsock32dll);
274 gs_wsock32dll = 0;
275 }
276
277 WSACleanup();
278 }
279
280 /* Per-socket GUI initialization / cleanup */
281
282 wxSocketImplMSW::wxSocketImplMSW(wxSocketBase& wxsocket)
283 : wxSocketImpl(wxsocket)
284 {
285 /* Allocate a new message number for this socket */
286 wxCRIT_SECT_LOCKER(lock, gs_critical);
287
288 int i = firstAvailable;
289 while (socketList[i] != NULL)
290 {
291 i = (i + 1) % MAXSOCKETS;
292
293 if (i == firstAvailable) /* abort! */
294 {
295 m_msgnumber = 0; // invalid
296 return;
297 }
298 }
299 socketList[i] = this;
300 firstAvailable = (i + 1) % MAXSOCKETS;
301 m_msgnumber = (i + WM_USER);
302 }
303
304 wxSocketImplMSW::~wxSocketImplMSW()
305 {
306 /* Remove the socket from the list */
307 wxCRIT_SECT_LOCKER(lock, gs_critical);
308
309 if ( m_msgnumber )
310 {
311 // we need to remove any pending messages for this socket to avoid having
312 // them sent to a new socket which could reuse the same message number as
313 // soon as we destroy this one
314 MSG msg;
315 while ( ::PeekMessage(&msg, hWin, m_msgnumber, m_msgnumber, PM_REMOVE) )
316 ;
317
318 socketList[m_msgnumber - WM_USER] = NULL;
319 }
320 //else: the socket has never been created successfully
321 }
322
323 /* Windows proc for asynchronous event handling */
324
325 LRESULT CALLBACK wxSocket_Internal_WinProc(HWND hWnd,
326 UINT uMsg,
327 WPARAM wParam,
328 LPARAM lParam)
329 {
330 if ( uMsg < WM_USER || uMsg > (WM_USER + MAXSOCKETS - 1))
331 return DefWindowProc(hWnd, uMsg, wParam, lParam);
332
333 wxSocketImplMSW *socket;
334 wxSocketNotify event;
335 {
336 wxCRIT_SECT_LOCKER(lock, gs_critical);
337
338 socket = socketList[(uMsg - WM_USER)];
339 event = (wxSocketNotify) -1;
340
341 /* Check that the socket still exists (it has not been
342 * destroyed) and for safety, check that the m_fd field
343 * is what we expect it to be.
344 */
345 if ((socket != NULL) && ((WPARAM)socket->m_fd == wParam))
346 {
347 switch WSAGETSELECTEVENT(lParam)
348 {
349 case FD_READ: event = wxSOCKET_INPUT; break;
350 case FD_WRITE: event = wxSOCKET_OUTPUT; break;
351 case FD_ACCEPT: event = wxSOCKET_CONNECTION; break;
352 case FD_CONNECT:
353 {
354 if (WSAGETSELECTERROR(lParam) != 0)
355 event = wxSOCKET_LOST;
356 else
357 event = wxSOCKET_CONNECTION;
358 break;
359 }
360 case FD_CLOSE: event = wxSOCKET_LOST; break;
361 }
362
363 if (event != -1)
364 {
365 if (event == wxSOCKET_LOST)
366 socket->m_detected = wxSOCKET_LOST_FLAG;
367 else
368 socket->m_detected |= (1 << event);
369 }
370 }
371 } // unlock gs_critical
372
373 if ( socket )
374 socket->NotifyOnStateChange(event);
375
376 return (LRESULT) 0;
377 }
378
379 /*
380 * Enable all event notifications; we need to be notified of all
381 * events for internal processing, but we will only notify users
382 * when an appropriate callback function has been installed.
383 */
384 void wxSocketMSWManager::Install_Callback(wxSocketImpl *socket_,
385 wxSocketNotify WXUNUSED(event))
386 {
387 wxSocketImplMSW * const socket = static_cast<wxSocketImplMSW *>(socket_);
388
389 if (socket->m_fd != INVALID_SOCKET)
390 {
391 /* We could probably just subscribe to all events regardless
392 * of the socket type, but MS recommends to do it this way.
393 */
394 long lEvent = socket->m_server?
395 FD_ACCEPT : (FD_READ | FD_WRITE | FD_CONNECT | FD_CLOSE);
396 #ifndef __WXWINCE__
397 gs_WSAAsyncSelect(socket->m_fd, hWin, socket->m_msgnumber, lEvent);
398 #else
399 /*
400 * WinCE creates a thread for socket event handling.
401 * All needed parameters get passed through the thread_data structure.
402 */
403
404 thread_data* d = new thread_data;
405 d->lEvent = lEvent;
406 d->hEvtWin = hWin;
407 d->msgnumber = socket->m_msgnumber;
408 d->fd = socket->m_fd;
409 socketHash[socket->m_fd] = true;
410 hThread[currSocket++] = CreateThread(NULL, 0, &SocketThread,(LPVOID)d, 0, NULL);
411 #endif
412 }
413 }
414
415 /*
416 * Disable event notifications (used when shutting down the socket)
417 */
418 void wxSocketMSWManager::Uninstall_Callback(wxSocketImpl *socket_,
419 wxSocketNotify WXUNUSED(event))
420 {
421 wxSocketImplMSW * const socket = static_cast<wxSocketImplMSW *>(socket_);
422
423 if (socket->m_fd != INVALID_SOCKET)
424 {
425 #ifndef __WXWINCE__
426 gs_WSAAsyncSelect(socket->m_fd, hWin, socket->m_msgnumber, 0);
427 #else
428 //Destroy the thread
429 socketHash[socket->m_fd] = false;
430 #endif
431 }
432 }
433
434 // set the wxBase variable to point to our wxSocketManager implementation
435 //
436 // see comments in wx/apptrait.h for the explanation of why do we do it
437 // like this
438 static struct ManagerSetter
439 {
440 ManagerSetter()
441 {
442 static wxSocketMSWManager s_manager;
443 wxAppTraits::SetDefaultSocketManager(&s_manager);
444 }
445 } gs_managerSetter;
446
447 // ============================================================================
448 // wxSocketImpl implementation
449 // ============================================================================
450
451 /* static */
452 wxSocketImpl *wxSocketImpl::Create(wxSocketBase& wxsocket)
453 {
454 return new wxSocketImplMSW(wxsocket);
455 }
456
457 void wxSocketImplMSW::DoClose()
458 {
459 wxSocketManager::Get()->
460 Uninstall_Callback(this, wxSOCKET_MAX_EVENT /* unused anyhow */);
461
462 closesocket(m_fd);
463 }
464
465 /*
466 * Waits for an incoming client connection. Returns a pointer to
467 * a wxSocketImpl object, or NULL if there was an error, in which case
468 * the last error field will be updated for the calling wxSocketImpl.
469 *
470 * Error codes (set in the calling wxSocketImpl)
471 * wxSOCKET_INVSOCK - the socket is not valid or not a server.
472 * wxSOCKET_TIMEDOUT - timeout, no incoming connections.
473 * wxSOCKET_WOULDBLOCK - the call would block and the socket is nonblocking.
474 * wxSOCKET_MEMERR - couldn't allocate memory.
475 * wxSOCKET_IOERR - low-level error.
476 */
477 wxSocketImpl *wxSocketImplMSW::WaitConnection(wxSocketBase& wxsocket)
478 {
479 wxSocketImpl *connection;
480 wxSockAddr from;
481 WX_SOCKLEN_T fromlen = sizeof(from);
482 wxSocketError err;
483 u_long arg = 1;
484
485 /* Reenable CONNECTION events */
486 m_detected &= ~wxSOCKET_CONNECTION_FLAG;
487
488 /* If the socket has already been created, we exit immediately */
489 if (m_fd == INVALID_SOCKET || !m_server)
490 {
491 m_error = wxSOCKET_INVSOCK;
492 return NULL;
493 }
494
495 /* Create a wxSocketImpl object for the new connection */
496 connection = wxSocketImplMSW::Create(wxsocket);
497
498 if (!connection)
499 {
500 m_error = wxSOCKET_MEMERR;
501 return NULL;
502 }
503
504 /* Wait for a connection (with timeout) */
505 if (Input_Timeout() == wxSOCKET_TIMEDOUT)
506 {
507 delete connection;
508 /* m_error set by Input_Timeout */
509 return NULL;
510 }
511
512 connection->m_fd = accept(m_fd, (sockaddr*)&from, &fromlen);
513
514 if (connection->m_fd == INVALID_SOCKET)
515 {
516 if (WSAGetLastError() == WSAEWOULDBLOCK)
517 m_error = wxSOCKET_WOULDBLOCK;
518 else
519 m_error = wxSOCKET_IOERR;
520
521 delete connection;
522 return NULL;
523 }
524
525 /* Initialize all fields */
526 connection->m_server = false;
527 connection->m_stream = true;
528
529 /* Setup the peer address field */
530 connection->m_peer = GAddress_new();
531 if (!connection->m_peer)
532 {
533 delete connection;
534 m_error = wxSOCKET_MEMERR;
535 return NULL;
536 }
537 err = _GAddress_translate_from(connection->m_peer, (sockaddr*)&from, fromlen);
538 if (err != wxSOCKET_NOERROR)
539 {
540 GAddress_destroy(connection->m_peer);
541 delete connection;
542 m_error = err;
543 return NULL;
544 }
545
546 ioctlsocket(connection->m_fd, FIONBIO, (u_long FAR *) &arg);
547 wxSocketManager::Get()->Install_Callback(connection);
548
549 return connection;
550 }
551
552 wxSocketError wxSocketImplMSW::DoHandleConnect(int ret)
553 {
554 // TODO: review this
555 if (ret == SOCKET_ERROR)
556 {
557 int err = WSAGetLastError();
558
559 /* If connect failed with EWOULDBLOCK and the wxSocketImpl object
560 * is in blocking mode, we select() for the specified timeout
561 * checking for writability to see if the connection request
562 * completes.
563 */
564 if ((err == WSAEWOULDBLOCK) && (!m_non_blocking))
565 {
566 err = Connect_Timeout();
567
568 if (err != wxSOCKET_NOERROR)
569 {
570 Close();
571 /* m_error is set in Connect_Timeout */
572 }
573
574 return (wxSocketError) err;
575 }
576
577 /* If connect failed with EWOULDBLOCK and the wxSocketImpl object
578 * is set to nonblocking, we set m_error to wxSOCKET_WOULDBLOCK
579 * (and return wxSOCKET_WOULDBLOCK) but we don't close the socket;
580 * this way if the connection completes, a wxSOCKET_CONNECTION
581 * event will be generated, if enabled.
582 */
583 if ((err == WSAEWOULDBLOCK) && (m_non_blocking))
584 {
585 m_establishing = true;
586 m_error = wxSOCKET_WOULDBLOCK;
587 return wxSOCKET_WOULDBLOCK;
588 }
589
590 /* If connect failed with an error other than EWOULDBLOCK,
591 * then the call to Connect() has failed.
592 */
593 Close();
594 m_error = wxSOCKET_IOERR;
595 return wxSOCKET_IOERR;
596 }
597
598 return wxSOCKET_NOERROR;
599 }
600
601 /* Generic IO */
602
603 /* Like recv(), send(), ... */
604 int wxSocketImplMSW::Read(void *buffer, int size)
605 {
606 int ret;
607
608 /* Reenable INPUT events */
609 m_detected &= ~wxSOCKET_INPUT_FLAG;
610
611 if (m_fd == INVALID_SOCKET || m_server)
612 {
613 m_error = wxSOCKET_INVSOCK;
614 return -1;
615 }
616
617 /* If the socket is blocking, wait for data (with a timeout) */
618 if (Input_Timeout() == wxSOCKET_TIMEDOUT)
619 {
620 m_error = wxSOCKET_TIMEDOUT;
621 return -1;
622 }
623
624 /* Read the data */
625 if (m_stream)
626 ret = Recv_Stream(buffer, size);
627 else
628 ret = Recv_Dgram(buffer, size);
629
630 if (ret == SOCKET_ERROR)
631 {
632 if (WSAGetLastError() != WSAEWOULDBLOCK)
633 m_error = wxSOCKET_IOERR;
634 else
635 m_error = wxSOCKET_WOULDBLOCK;
636 return -1;
637 }
638
639 return ret;
640 }
641
642 int wxSocketImplMSW::Write(const void *buffer, int size)
643 {
644 int ret;
645
646 if (m_fd == INVALID_SOCKET || m_server)
647 {
648 m_error = wxSOCKET_INVSOCK;
649 return -1;
650 }
651
652 /* If the socket is blocking, wait for writability (with a timeout) */
653 if (Output_Timeout() == wxSOCKET_TIMEDOUT)
654 return -1;
655
656 /* Write the data */
657 if (m_stream)
658 ret = Send_Stream(buffer, size);
659 else
660 ret = Send_Dgram(buffer, size);
661
662 if (ret == SOCKET_ERROR)
663 {
664 if (WSAGetLastError() != WSAEWOULDBLOCK)
665 m_error = wxSOCKET_IOERR;
666 else
667 m_error = wxSOCKET_WOULDBLOCK;
668
669 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
670 * does). Once the first OUTPUT event is received, users can assume
671 * that the socket is writable until a read operation fails. Only then
672 * will further OUTPUT events be posted.
673 */
674 m_detected &= ~wxSOCKET_OUTPUT_FLAG;
675 return -1;
676 }
677
678 return ret;
679 }
680
681 /* Internals (IO) */
682
683 /*
684 * For blocking sockets, wait until data is available or
685 * until timeout ellapses.
686 */
687 wxSocketError wxSocketImplMSW::Input_Timeout()
688 {
689 fd_set readfds;
690
691 if (!m_non_blocking)
692 {
693 FD_ZERO(&readfds);
694 FD_SET(m_fd, &readfds);
695 if (select(0, &readfds, NULL, NULL, &m_timeout) == 0)
696 {
697 m_error = wxSOCKET_TIMEDOUT;
698 return wxSOCKET_TIMEDOUT;
699 }
700 }
701 return wxSOCKET_NOERROR;
702 }
703
704 /*
705 * For blocking sockets, wait until data can be sent without
706 * blocking or until timeout ellapses.
707 */
708 wxSocketError wxSocketImplMSW::Output_Timeout()
709 {
710 fd_set writefds;
711
712 if (!m_non_blocking)
713 {
714 FD_ZERO(&writefds);
715 FD_SET(m_fd, &writefds);
716 if (select(0, NULL, &writefds, NULL, &m_timeout) == 0)
717 {
718 m_error = wxSOCKET_TIMEDOUT;
719 return wxSOCKET_TIMEDOUT;
720 }
721 }
722 return wxSOCKET_NOERROR;
723 }
724
725 /*
726 * For blocking sockets, wait until the connection is
727 * established or fails, or until timeout ellapses.
728 */
729 wxSocketError wxSocketImplMSW::Connect_Timeout()
730 {
731 fd_set writefds;
732 fd_set exceptfds;
733
734 FD_ZERO(&writefds);
735 FD_ZERO(&exceptfds);
736 FD_SET(m_fd, &writefds);
737 FD_SET(m_fd, &exceptfds);
738 if (select(0, NULL, &writefds, &exceptfds, &m_timeout) == 0)
739 {
740 m_error = wxSOCKET_TIMEDOUT;
741 return wxSOCKET_TIMEDOUT;
742 }
743 if (!FD_ISSET(m_fd, &writefds))
744 {
745 m_error = wxSOCKET_IOERR;
746 return wxSOCKET_IOERR;
747 }
748
749 return wxSOCKET_NOERROR;
750 }
751
752 int wxSocketImplMSW::Recv_Stream(void *buffer, int size)
753 {
754 return recv(m_fd, static_cast<char *>(buffer), size, 0);
755 }
756
757 int wxSocketImplMSW::Recv_Dgram(void *buffer, int size)
758 {
759 wxSockAddr from;
760 WX_SOCKLEN_T fromlen = sizeof(from);
761 int ret;
762 wxSocketError err;
763
764 ret = recvfrom(m_fd, static_cast<char *>(buffer),
765 size, 0, &from, &fromlen);
766
767 if (ret == SOCKET_ERROR)
768 return SOCKET_ERROR;
769
770 /* Translate a system address into a wxSocketImpl address */
771 if (!m_peer)
772 {
773 m_peer = GAddress_new();
774 if (!m_peer)
775 {
776 m_error = wxSOCKET_MEMERR;
777 return -1;
778 }
779 }
780 err = _GAddress_translate_from(m_peer, (sockaddr*)&from, fromlen);
781 if (err != wxSOCKET_NOERROR)
782 {
783 GAddress_destroy(m_peer);
784 m_peer = NULL;
785 m_error = err;
786 return -1;
787 }
788
789 return ret;
790 }
791
792 int wxSocketImplMSW::Send_Stream(const void *buffer, int size)
793 {
794 return send(m_fd, static_cast<const char *>(buffer), size, 0);
795 }
796
797 int wxSocketImplMSW::Send_Dgram(const void *buffer, int size)
798 {
799 struct sockaddr *addr;
800 int len, ret;
801 wxSocketError err;
802
803 if (!m_peer)
804 {
805 m_error = wxSOCKET_INVADDR;
806 return -1;
807 }
808
809 err = _GAddress_translate_to(m_peer, &addr, &len);
810 if (err != wxSOCKET_NOERROR)
811 {
812 m_error = err;
813 return -1;
814 }
815
816 ret = sendto(m_fd, static_cast<const char *>(buffer), size, 0, addr, len);
817
818 /* Frees memory allocated by _GAddress_translate_to */
819 free(addr);
820
821 return ret;
822 }
823
824 /*
825 * -------------------------------------------------------------------------
826 * GAddress
827 * -------------------------------------------------------------------------
828 */
829
830 /* CHECK_ADDRESS verifies that the current address family is either
831 * wxSOCKET_NOFAMILY or wxSOCKET_*family*, and if it is wxSOCKET_NOFAMILY, it
832 * initalizes it to be a wxSOCKET_*family*. In other cases, it returns
833 * an appropiate error code.
834 *
835 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
836 */
837 #define CHECK_ADDRESS(address, family) \
838 { \
839 if (address->m_family == wxSOCKET_NOFAMILY) \
840 if (_GAddress_Init_##family(address) != wxSOCKET_NOERROR) \
841 return address->m_error; \
842 if (address->m_family != wxSOCKET_##family) \
843 { \
844 address->m_error = wxSOCKET_INVADDR; \
845 return wxSOCKET_INVADDR; \
846 } \
847 }
848
849 #define CHECK_ADDRESS_RETVAL(address, family, retval) \
850 { \
851 if (address->m_family == wxSOCKET_NOFAMILY) \
852 if (_GAddress_Init_##family(address) != wxSOCKET_NOERROR) \
853 return retval; \
854 if (address->m_family != wxSOCKET_##family) \
855 { \
856 address->m_error = wxSOCKET_INVADDR; \
857 return retval; \
858 } \
859 }
860
861
862 GAddress *GAddress_new()
863 {
864 GAddress *address;
865
866 if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
867 return NULL;
868
869 address->m_family = wxSOCKET_NOFAMILY;
870 address->m_addr = NULL;
871 address->m_len = 0;
872
873 return address;
874 }
875
876 GAddress *GAddress_copy(GAddress *address)
877 {
878 GAddress *addr2;
879
880 if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
881 return NULL;
882
883 memcpy(addr2, address, sizeof(GAddress));
884
885 if (address->m_addr)
886 {
887 addr2->m_addr = (struct sockaddr *) malloc(addr2->m_len);
888 if (addr2->m_addr == NULL)
889 {
890 free(addr2);
891 return NULL;
892 }
893 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
894 }
895
896 return addr2;
897 }
898
899 void GAddress_destroy(GAddress *address)
900 {
901 if (address->m_addr)
902 free(address->m_addr);
903
904 free(address);
905 }
906
907 void GAddress_SetFamily(GAddress *address, GAddressType type)
908 {
909 address->m_family = type;
910 }
911
912 GAddressType GAddress_GetFamily(GAddress *address)
913 {
914 return address->m_family;
915 }
916
917 wxSocketError _GAddress_translate_from(GAddress *address,
918 struct sockaddr *addr, int len)
919 {
920 address->m_realfamily = addr->sa_family;
921 switch (addr->sa_family)
922 {
923 case AF_INET:
924 address->m_family = wxSOCKET_INET;
925 break;
926 case AF_UNIX:
927 address->m_family = wxSOCKET_UNIX;
928 break;
929 #if wxUSE_IPV6
930 case AF_INET6:
931 address->m_family = wxSOCKET_INET6;
932 break;
933 #endif
934 default:
935 {
936 address->m_error = wxSOCKET_INVOP;
937 return wxSOCKET_INVOP;
938 }
939 }
940
941 if (address->m_addr)
942 free(address->m_addr);
943
944 address->m_len = len;
945 address->m_addr = (struct sockaddr *) malloc(len);
946
947 if (address->m_addr == NULL)
948 {
949 address->m_error = wxSOCKET_MEMERR;
950 return wxSOCKET_MEMERR;
951 }
952 memcpy(address->m_addr, addr, len);
953
954 return wxSOCKET_NOERROR;
955 }
956
957 wxSocketError _GAddress_translate_to(GAddress *address,
958 struct sockaddr **addr, int *len)
959 {
960 if (!address->m_addr)
961 {
962 address->m_error = wxSOCKET_INVADDR;
963 return wxSOCKET_INVADDR;
964 }
965
966 *len = address->m_len;
967 *addr = (struct sockaddr *) malloc(address->m_len);
968 if (*addr == NULL)
969 {
970 address->m_error = wxSOCKET_MEMERR;
971 return wxSOCKET_MEMERR;
972 }
973
974 memcpy(*addr, address->m_addr, address->m_len);
975 return wxSOCKET_NOERROR;
976 }
977
978 /*
979 * -------------------------------------------------------------------------
980 * Internet address family
981 * -------------------------------------------------------------------------
982 */
983
984 wxSocketError _GAddress_Init_INET(GAddress *address)
985 {
986 address->m_len = sizeof(struct sockaddr_in);
987 address->m_addr = (struct sockaddr *) malloc(address->m_len);
988 if (address->m_addr == NULL)
989 {
990 address->m_error = wxSOCKET_MEMERR;
991 return wxSOCKET_MEMERR;
992 }
993
994 address->m_family = wxSOCKET_INET;
995 address->m_realfamily = AF_INET;
996 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
997 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
998
999 return wxSOCKET_NOERROR;
1000 }
1001
1002 wxSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
1003 {
1004 struct hostent *he;
1005 struct in_addr *addr;
1006
1007 CHECK_ADDRESS(address, INET);
1008
1009 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1010
1011 addr->s_addr = inet_addr(hostname);
1012
1013 /* If it is a numeric host name, convert it now */
1014 if (addr->s_addr == INADDR_NONE)
1015 {
1016 struct in_addr *array_addr;
1017
1018 /* It is a real name, we solve it */
1019 if ((he = gethostbyname(hostname)) == NULL)
1020 {
1021 /* addr->s_addr = INADDR_NONE just done by inet_addr() above */
1022 address->m_error = wxSOCKET_NOHOST;
1023 return wxSOCKET_NOHOST;
1024 }
1025 array_addr = (struct in_addr *) *(he->h_addr_list);
1026 addr->s_addr = array_addr[0].s_addr;
1027 }
1028 return wxSOCKET_NOERROR;
1029 }
1030
1031 wxSocketError GAddress_INET_SetBroadcastAddress(GAddress *address)
1032 {
1033 return GAddress_INET_SetHostAddress(address, INADDR_BROADCAST);
1034 }
1035
1036 wxSocketError GAddress_INET_SetAnyAddress(GAddress *address)
1037 {
1038 return GAddress_INET_SetHostAddress(address, INADDR_ANY);
1039 }
1040
1041 wxSocketError GAddress_INET_SetHostAddress(GAddress *address,
1042 unsigned long hostaddr)
1043 {
1044 struct in_addr *addr;
1045
1046 CHECK_ADDRESS(address, INET);
1047
1048 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1049 addr->s_addr = htonl(hostaddr);
1050
1051 return wxSOCKET_NOERROR;
1052 }
1053
1054 wxSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
1055 const char *protocol)
1056 {
1057 struct servent *se;
1058 struct sockaddr_in *addr;
1059
1060 CHECK_ADDRESS(address, INET);
1061
1062 if (!port)
1063 {
1064 address->m_error = wxSOCKET_INVPORT;
1065 return wxSOCKET_INVPORT;
1066 }
1067
1068 se = getservbyname(port, protocol);
1069 if (!se)
1070 {
1071 if (isdigit(port[0]))
1072 {
1073 int port_int;
1074
1075 port_int = atoi(port);
1076 addr = (struct sockaddr_in *)address->m_addr;
1077 addr->sin_port = htons((u_short) port_int);
1078 return wxSOCKET_NOERROR;
1079 }
1080
1081 address->m_error = wxSOCKET_INVPORT;
1082 return wxSOCKET_INVPORT;
1083 }
1084
1085 addr = (struct sockaddr_in *)address->m_addr;
1086 addr->sin_port = se->s_port;
1087
1088 return wxSOCKET_NOERROR;
1089 }
1090
1091 wxSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
1092 {
1093 struct sockaddr_in *addr;
1094
1095 CHECK_ADDRESS(address, INET);
1096
1097 addr = (struct sockaddr_in *)address->m_addr;
1098 addr->sin_port = htons(port);
1099
1100 return wxSOCKET_NOERROR;
1101 }
1102
1103 wxSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1104 {
1105 struct hostent *he;
1106 char *addr_buf;
1107 struct sockaddr_in *addr;
1108
1109 CHECK_ADDRESS(address, INET);
1110
1111 addr = (struct sockaddr_in *)address->m_addr;
1112 addr_buf = (char *)&(addr->sin_addr);
1113
1114 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
1115 if (he == NULL)
1116 {
1117 address->m_error = wxSOCKET_NOHOST;
1118 return wxSOCKET_NOHOST;
1119 }
1120
1121 strncpy(hostname, he->h_name, sbuf);
1122
1123 return wxSOCKET_NOERROR;
1124 }
1125
1126 unsigned long GAddress_INET_GetHostAddress(GAddress *address)
1127 {
1128 struct sockaddr_in *addr;
1129
1130 CHECK_ADDRESS_RETVAL(address, INET, 0);
1131
1132 addr = (struct sockaddr_in *)address->m_addr;
1133
1134 return ntohl(addr->sin_addr.s_addr);
1135 }
1136
1137 unsigned short GAddress_INET_GetPort(GAddress *address)
1138 {
1139 struct sockaddr_in *addr;
1140
1141 CHECK_ADDRESS_RETVAL(address, INET, 0);
1142
1143 addr = (struct sockaddr_in *)address->m_addr;
1144 return ntohs(addr->sin_port);
1145 }
1146
1147
1148 #if wxUSE_IPV6
1149 /*
1150 * -------------------------------------------------------------------------
1151 * Internet IPv6 address family
1152 * -------------------------------------------------------------------------
1153 */
1154 #include "ws2tcpip.h"
1155
1156 #ifdef __VISUALC__
1157 #pragma comment(lib,"ws2_32")
1158 #endif // __VISUALC__
1159
1160 wxSocketError _GAddress_Init_INET6(GAddress *address)
1161 {
1162 struct in6_addr any_address = IN6ADDR_ANY_INIT;
1163 address->m_len = sizeof(struct sockaddr_in6);
1164 address->m_addr = (struct sockaddr *) malloc(address->m_len);
1165 if (address->m_addr == NULL)
1166 {
1167 address->m_error = wxSOCKET_MEMERR;
1168 return wxSOCKET_MEMERR;
1169 }
1170 memset(address->m_addr,0,address->m_len);
1171
1172 address->m_family = wxSOCKET_INET6;
1173 address->m_realfamily = AF_INET6;
1174 ((struct sockaddr_in6 *)address->m_addr)->sin6_family = AF_INET6;
1175 ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = any_address;
1176
1177 return wxSOCKET_NOERROR;
1178 }
1179
1180 wxSocketError GAddress_INET6_SetHostName(GAddress *address, const char *hostname)
1181 {
1182 CHECK_ADDRESS(address, INET6);
1183
1184 addrinfo hints;
1185 memset( & hints, 0, sizeof( hints ) );
1186 hints.ai_family = AF_INET6;
1187 addrinfo * info = 0;
1188 if ( getaddrinfo( hostname, "0", & hints, & info ) || ! info )
1189 {
1190 address->m_error = wxSOCKET_NOHOST;
1191 return wxSOCKET_NOHOST;
1192 }
1193
1194 memcpy( address->m_addr, info->ai_addr, info->ai_addrlen );
1195 freeaddrinfo( info );
1196 return wxSOCKET_NOERROR;
1197 }
1198
1199 wxSocketError GAddress_INET6_SetAnyAddress(GAddress *address)
1200 {
1201 CHECK_ADDRESS(address, INET6);
1202
1203 struct in6_addr addr;
1204 memset( & addr, 0, sizeof( addr ) );
1205 return GAddress_INET6_SetHostAddress(address, addr);
1206 }
1207 wxSocketError GAddress_INET6_SetHostAddress(GAddress *address,
1208 struct in6_addr hostaddr)
1209 {
1210 CHECK_ADDRESS(address, INET6);
1211
1212 ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = hostaddr;
1213
1214 return wxSOCKET_NOERROR;
1215 }
1216
1217 wxSocketError GAddress_INET6_SetPortName(GAddress *address, const char *port,
1218 const char *protocol)
1219 {
1220 struct servent *se;
1221 struct sockaddr_in6 *addr;
1222
1223 CHECK_ADDRESS(address, INET6);
1224
1225 if (!port)
1226 {
1227 address->m_error = wxSOCKET_INVPORT;
1228 return wxSOCKET_INVPORT;
1229 }
1230
1231 se = getservbyname(port, protocol);
1232 if (!se)
1233 {
1234 if (isdigit((unsigned char) port[0]))
1235 {
1236 int port_int;
1237
1238 port_int = atoi(port);
1239 addr = (struct sockaddr_in6 *)address->m_addr;
1240 addr->sin6_port = htons((u_short) port_int);
1241 return wxSOCKET_NOERROR;
1242 }
1243
1244 address->m_error = wxSOCKET_INVPORT;
1245 return wxSOCKET_INVPORT;
1246 }
1247
1248 addr = (struct sockaddr_in6 *)address->m_addr;
1249 addr->sin6_port = se->s_port;
1250
1251 return wxSOCKET_NOERROR;
1252 }
1253
1254 wxSocketError GAddress_INET6_SetPort(GAddress *address, unsigned short port)
1255 {
1256 struct sockaddr_in6 *addr;
1257
1258 CHECK_ADDRESS(address, INET6);
1259
1260 addr = (struct sockaddr_in6 *)address->m_addr;
1261 addr->sin6_port = htons(port);
1262
1263 return wxSOCKET_NOERROR;
1264 }
1265
1266 wxSocketError GAddress_INET6_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1267 {
1268 struct hostent *he;
1269 char *addr_buf;
1270 struct sockaddr_in6 *addr;
1271
1272 CHECK_ADDRESS(address, INET6);
1273
1274 addr = (struct sockaddr_in6 *)address->m_addr;
1275 addr_buf = (char *)&(addr->sin6_addr);
1276
1277 he = gethostbyaddr(addr_buf, sizeof(addr->sin6_addr), AF_INET6);
1278 if (he == NULL)
1279 {
1280 address->m_error = wxSOCKET_NOHOST;
1281 return wxSOCKET_NOHOST;
1282 }
1283
1284 strncpy(hostname, he->h_name, sbuf);
1285
1286 return wxSOCKET_NOERROR;
1287 }
1288
1289 wxSocketError GAddress_INET6_GetHostAddress(GAddress *address,struct in6_addr *hostaddr)
1290 {
1291 CHECK_ADDRESS_RETVAL(address, INET6, wxSOCKET_INVADDR);
1292 *hostaddr = ( (struct sockaddr_in6 *)address->m_addr )->sin6_addr;
1293 return wxSOCKET_NOERROR;
1294 }
1295
1296 unsigned short GAddress_INET6_GetPort(GAddress *address)
1297 {
1298 CHECK_ADDRESS_RETVAL(address, INET6, 0);
1299
1300 return ntohs( ((struct sockaddr_in6 *)address->m_addr)->sin6_port );
1301 }
1302
1303 #endif // wxUSE_IPV6
1304
1305 /*
1306 * -------------------------------------------------------------------------
1307 * Unix address family
1308 * -------------------------------------------------------------------------
1309 */
1310
1311 wxSocketError _GAddress_Init_UNIX(GAddress *address)
1312 {
1313 address->m_error = wxSOCKET_INVADDR;
1314 return wxSOCKET_INVADDR;
1315 }
1316
1317 wxSocketError GAddress_UNIX_SetPath(GAddress *address, const char *WXUNUSED(path))
1318 {
1319 address->m_error = wxSOCKET_INVADDR;
1320 return wxSOCKET_INVADDR;
1321 }
1322
1323 wxSocketError GAddress_UNIX_GetPath(GAddress *address, char *WXUNUSED(path), size_t WXUNUSED(sbuf))
1324 {
1325 address->m_error = wxSOCKET_INVADDR;
1326 return wxSOCKET_INVADDR;
1327 }
1328
1329 #endif // wxUSE_SOCKETS