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