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