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