]> git.saurik.com Git - wxWidgets.git/blob - src/msw/gsocket.cpp
catch unhandled exceptions in POSIX threads implementation the same way wxMSW does
[wxWidgets.git] / src / msw / gsocket.cpp
1 /* -------------------------------------------------------------------------
2 * Project: GSocket (Generic Socket)
3 * Name: src/msw/gsocket.cpp
4 * Copyright: (c) Guilhem Lavaux
5 * Licence: wxWindows Licence
6 * Author: Guillermo Rodriguez Garcia <guille@iies.es>
7 * Purpose: GSocket main MSW file
8 * Licence: The wxWindows licence
9 * CVSID: $Id$
10 * -------------------------------------------------------------------------
11 */
12
13 // For compilers that support precompilation, includes "wx.h".
14 #include "wx/wxprec.h"
15
16 #ifdef __BORLANDC__
17 #pragma hdrstop
18 #endif
19
20 #ifdef _MSC_VER
21 /* RPCNOTIFICATION_ROUTINE in rasasync.h (included from winsock.h),
22 * warning: conditional expression is constant.
23 */
24 # pragma warning(disable:4115)
25 /* FD_SET,
26 * warning: named type definition in parentheses.
27 */
28 # pragma warning(disable:4127)
29 /* GAddress_UNIX_GetPath,
30 * warning: unreferenced formal parameter.
31 */
32 # pragma warning(disable:4100)
33
34 #ifdef __WXWINCE__
35 /* windows.h results in tons of warnings at max warning level */
36 # ifdef _MSC_VER
37 # pragma warning(push, 1)
38 # endif
39 # include <windows.h>
40 # ifdef _MSC_VER
41 # pragma warning(pop)
42 # pragma warning(disable:4514)
43 # endif
44 #endif
45
46 #endif /* _MSC_VER */
47
48 #if defined(__CYGWIN__)
49 //CYGWIN gives annoying warning about runtime stuff if we don't do this
50 # define USE_SYS_TYPES_FD_SET
51 # include <sys/types.h>
52 #endif
53
54 #include <winsock.h>
55
56 #ifndef __GSOCKET_STANDALONE__
57 # include "wx/platform.h"
58 #endif
59
60 #if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
61
62 #ifndef __GSOCKET_STANDALONE__
63 # include "wx/msw/gsockmsw.h"
64 # include "wx/gsocket.h"
65 #else
66 # include "gsockmsw.h"
67 # include "gsocket.h"
68 #endif /* __GSOCKET_STANDALONE__ */
69
70 #ifndef __WXWINCE__
71 #include <assert.h>
72 #else
73 #define assert(x)
74 #ifndef isdigit
75 #define isdigit(x) (x > 47 && x < 58)
76 #endif
77 #include "wx/msw/wince/net.h"
78 #endif
79
80 #include <string.h>
81 #include <stdio.h>
82 #include <stdlib.h>
83 #include <stddef.h>
84 #include <ctype.h>
85
86 /* if we use configure for MSW WX_SOCKLEN_T will be already defined */
87 #ifndef WX_SOCKLEN_T
88 # define WX_SOCKLEN_T int
89 #endif
90
91 #if wxUSE_IPV6
92 typedef struct sockaddr_storage wxSockAddr;
93 #else
94 typedef struct sockaddr wxSockAddr;
95 #endif
96
97
98 /* Table of GUI-related functions. We must call them indirectly because
99 * of wxBase and GUI separation: */
100
101 static GSocketGUIFunctionsTable *gs_gui_functions;
102
103 class GSocketGUIFunctionsTableNull: public GSocketGUIFunctionsTable
104 {
105 public:
106 virtual bool OnInit();
107 virtual void OnExit();
108 virtual bool CanUseEventLoop();
109 virtual bool Init_Socket(GSocket *socket);
110 virtual void Destroy_Socket(GSocket *socket);
111 virtual void Enable_Events(GSocket *socket);
112 virtual void Disable_Events(GSocket *socket);
113 };
114
115 bool GSocketGUIFunctionsTableNull::OnInit()
116 { return true; }
117 void GSocketGUIFunctionsTableNull::OnExit()
118 {}
119 bool GSocketGUIFunctionsTableNull::CanUseEventLoop()
120 { return false; }
121 bool GSocketGUIFunctionsTableNull::Init_Socket(GSocket *WXUNUSED(socket))
122 { return true; }
123 void GSocketGUIFunctionsTableNull::Destroy_Socket(GSocket *WXUNUSED(socket))
124 {}
125 void GSocketGUIFunctionsTableNull::Enable_Events(GSocket *WXUNUSED(socket))
126 {}
127 void GSocketGUIFunctionsTableNull::Disable_Events(GSocket *WXUNUSED(socket))
128 {}
129 /* Global initialisers */
130
131 void GSocket_SetGUIFunctions(GSocketGUIFunctionsTable *guifunc)
132 {
133 gs_gui_functions = guifunc;
134 }
135
136 int GSocket_Init(void)
137 {
138 WSADATA wsaData;
139
140 if (!gs_gui_functions)
141 {
142 static GSocketGUIFunctionsTableNull table;
143 gs_gui_functions = &table;
144 }
145 if ( !gs_gui_functions->OnInit() )
146 {
147 return 0;
148 }
149
150 /* Initialize WinSocket */
151 return (WSAStartup((1 << 8) | 1, &wsaData) == 0);
152 }
153
154 void GSocket_Cleanup(void)
155 {
156 if (gs_gui_functions)
157 {
158 gs_gui_functions->OnExit();
159 }
160
161 /* Cleanup WinSocket */
162 WSACleanup();
163 }
164
165 /* Constructors / Destructors for GSocket */
166
167 GSocket::GSocket()
168 {
169 int i;
170
171 m_fd = INVALID_SOCKET;
172 for (i = 0; i < GSOCK_MAX_EVENT; i++)
173 {
174 m_cbacks[i] = NULL;
175 }
176 m_detected = 0;
177 m_local = NULL;
178 m_peer = NULL;
179 m_error = GSOCK_NOERROR;
180 m_server = false;
181 m_stream = true;
182 m_non_blocking = false;
183 m_timeout.tv_sec = 10 * 60; /* 10 minutes */
184 m_timeout.tv_usec = 0;
185 m_establishing = false;
186 m_reusable = false;
187 m_broadcast = false;
188 m_dobind = true;
189 m_initialRecvBufferSize = -1;
190 m_initialSendBufferSize = -1;
191
192 assert(gs_gui_functions);
193 /* Per-socket GUI-specific initialization */
194 m_ok = gs_gui_functions->Init_Socket(this);
195 }
196
197 void GSocket::Close()
198 {
199 gs_gui_functions->Disable_Events(this);
200 closesocket(m_fd);
201 m_fd = INVALID_SOCKET;
202 }
203
204 GSocket::~GSocket()
205 {
206 assert(this);
207
208 /* Per-socket GUI-specific cleanup */
209 gs_gui_functions->Destroy_Socket(this);
210
211 /* Check that the socket is really shutdowned */
212 if (m_fd != INVALID_SOCKET)
213 Shutdown();
214
215 /* Destroy private addresses */
216 if (m_local)
217 GAddress_destroy(m_local);
218
219 if (m_peer)
220 GAddress_destroy(m_peer);
221 }
222
223 /* GSocket_Shutdown:
224 * Disallow further read/write operations on this socket, close
225 * the fd and disable all callbacks.
226 */
227 void GSocket::Shutdown()
228 {
229 int evt;
230
231 assert(this);
232
233 /* If socket has been created, shutdown it */
234 if (m_fd != INVALID_SOCKET)
235 {
236 shutdown(m_fd, 1 /* SD_SEND */);
237 Close();
238 }
239
240 /* Disable GUI callbacks */
241 for (evt = 0; evt < GSOCK_MAX_EVENT; evt++)
242 m_cbacks[evt] = NULL;
243
244 m_detected = GSOCK_LOST_FLAG;
245 }
246
247 /* Address handling */
248
249 /* GSocket_SetLocal:
250 * GSocket_GetLocal:
251 * GSocket_SetPeer:
252 * GSocket_GetPeer:
253 * Set or get the local or peer address for this socket. The 'set'
254 * functions return GSOCK_NOERROR on success, an error code otherwise.
255 * The 'get' functions return a pointer to a GAddress object on success,
256 * or NULL otherwise, in which case they set the error code of the
257 * corresponding GSocket.
258 *
259 * Error codes:
260 * GSOCK_INVSOCK - the socket is not valid.
261 * GSOCK_INVADDR - the address is not valid.
262 */
263 GSocketError GSocket::SetLocal(GAddress *address)
264 {
265 assert(this);
266
267 /* the socket must be initialized, or it must be a server */
268 if (m_fd != INVALID_SOCKET && !m_server)
269 {
270 m_error = GSOCK_INVSOCK;
271 return GSOCK_INVSOCK;
272 }
273
274 /* check address */
275 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
276 {
277 m_error = GSOCK_INVADDR;
278 return GSOCK_INVADDR;
279 }
280
281 if (m_local)
282 GAddress_destroy(m_local);
283
284 m_local = GAddress_copy(address);
285
286 return GSOCK_NOERROR;
287 }
288
289 GSocketError GSocket::SetPeer(GAddress *address)
290 {
291 assert(this);
292
293 /* check address */
294 if (address == NULL || address->m_family == GSOCK_NOFAMILY)
295 {
296 m_error = GSOCK_INVADDR;
297 return GSOCK_INVADDR;
298 }
299
300 if (m_peer)
301 GAddress_destroy(m_peer);
302
303 m_peer = GAddress_copy(address);
304
305 return GSOCK_NOERROR;
306 }
307
308 GAddress *GSocket::GetLocal()
309 {
310 GAddress *address;
311 wxSockAddr addr;
312 WX_SOCKLEN_T size = sizeof(addr);
313 GSocketError err;
314
315 assert(this);
316
317 /* try to get it from the m_local var first */
318 if (m_local)
319 return GAddress_copy(m_local);
320
321 /* else, if the socket is initialized, try getsockname */
322 if (m_fd == INVALID_SOCKET)
323 {
324 m_error = GSOCK_INVSOCK;
325 return NULL;
326 }
327
328 if (getsockname(m_fd, (sockaddr*)&addr, &size) == SOCKET_ERROR)
329 {
330 m_error = GSOCK_IOERR;
331 return NULL;
332 }
333
334 /* got a valid address from getsockname, create a GAddress object */
335 if ((address = GAddress_new()) == NULL)
336 {
337 m_error = GSOCK_MEMERR;
338 return NULL;
339 }
340
341 if ((err = _GAddress_translate_from(address, (sockaddr*)&addr, size)) != GSOCK_NOERROR)
342 {
343 GAddress_destroy(address);
344 m_error = err;
345 return NULL;
346 }
347
348 return address;
349 }
350
351 GAddress *GSocket::GetPeer()
352 {
353 assert(this);
354
355 /* try to get it from the m_peer var */
356 if (m_peer)
357 return GAddress_copy(m_peer);
358
359 return NULL;
360 }
361
362 /* Server specific parts */
363
364 /* GSocket_SetServer:
365 * Sets up this socket as a server. The local address must have been
366 * set with GSocket_SetLocal() before GSocket_SetServer() is called.
367 * Returns GSOCK_NOERROR on success, one of the following otherwise:
368 *
369 * Error codes:
370 * GSOCK_INVSOCK - the socket is in use.
371 * GSOCK_INVADDR - the local address has not been set.
372 * GSOCK_IOERR - low-level error.
373 */
374 GSocketError GSocket::SetServer()
375 {
376 u_long arg = 1;
377
378 assert(this);
379
380 /* must not be in use */
381 if (m_fd != INVALID_SOCKET)
382 {
383 m_error = GSOCK_INVSOCK;
384 return GSOCK_INVSOCK;
385 }
386
387 /* the local addr must have been set */
388 if (!m_local)
389 {
390 m_error = GSOCK_INVADDR;
391 return GSOCK_INVADDR;
392 }
393
394 /* Initialize all fields */
395 m_server = true;
396 m_stream = true;
397
398 /* Create the socket */
399 m_fd = socket(m_local->m_realfamily, SOCK_STREAM, 0);
400
401 if (m_fd == INVALID_SOCKET)
402 {
403 m_error = GSOCK_IOERR;
404 return GSOCK_IOERR;
405 }
406
407 ioctlsocket(m_fd, FIONBIO, (u_long FAR *) &arg);
408 gs_gui_functions->Enable_Events(this);
409
410 /* allow a socket to re-bind if the socket is in the TIME_WAIT
411 state after being previously closed.
412 */
413 if (m_reusable)
414 {
415 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(arg));
416 }
417
418 /* Bind to the local address,
419 * retrieve the actual address bound,
420 * and listen up to 5 connections.
421 */
422 if ((bind(m_fd, m_local->m_addr, m_local->m_len) != 0) ||
423 (getsockname(m_fd,
424 m_local->m_addr,
425 (WX_SOCKLEN_T *)&m_local->m_len) != 0) ||
426 (listen(m_fd, 5) != 0))
427 {
428 Close();
429 m_error = GSOCK_IOERR;
430 return GSOCK_IOERR;
431 }
432
433 return GSOCK_NOERROR;
434 }
435
436 /* GSocket_WaitConnection:
437 * Waits for an incoming client connection. Returns a pointer to
438 * a GSocket object, or NULL if there was an error, in which case
439 * the last error field will be updated for the calling GSocket.
440 *
441 * Error codes (set in the calling GSocket)
442 * GSOCK_INVSOCK - the socket is not valid or not a server.
443 * GSOCK_TIMEDOUT - timeout, no incoming connections.
444 * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
445 * GSOCK_MEMERR - couldn't allocate memory.
446 * GSOCK_IOERR - low-level error.
447 */
448 GSocket *GSocket::WaitConnection()
449 {
450 GSocket *connection;
451 wxSockAddr from;
452 WX_SOCKLEN_T fromlen = sizeof(from);
453 GSocketError err;
454 u_long arg = 1;
455
456 assert(this);
457
458 /* Reenable CONNECTION events */
459 m_detected &= ~GSOCK_CONNECTION_FLAG;
460
461 /* If the socket has already been created, we exit immediately */
462 if (m_fd == INVALID_SOCKET || !m_server)
463 {
464 m_error = GSOCK_INVSOCK;
465 return NULL;
466 }
467
468 /* Create a GSocket object for the new connection */
469 connection = GSocket_new();
470
471 if (!connection)
472 {
473 m_error = GSOCK_MEMERR;
474 return NULL;
475 }
476
477 /* Wait for a connection (with timeout) */
478 if (Input_Timeout() == GSOCK_TIMEDOUT)
479 {
480 delete connection;
481 /* m_error set by _GSocket_Input_Timeout */
482 return NULL;
483 }
484
485 connection->m_fd = accept(m_fd, (sockaddr*)&from, &fromlen);
486
487 if (connection->m_fd == INVALID_SOCKET)
488 {
489 if (WSAGetLastError() == WSAEWOULDBLOCK)
490 m_error = GSOCK_WOULDBLOCK;
491 else
492 m_error = GSOCK_IOERR;
493
494 delete connection;
495 return NULL;
496 }
497
498 /* Initialize all fields */
499 connection->m_server = false;
500 connection->m_stream = true;
501
502 /* Setup the peer address field */
503 connection->m_peer = GAddress_new();
504 if (!connection->m_peer)
505 {
506 delete connection;
507 m_error = GSOCK_MEMERR;
508 return NULL;
509 }
510 err = _GAddress_translate_from(connection->m_peer, (sockaddr*)&from, fromlen);
511 if (err != GSOCK_NOERROR)
512 {
513 GAddress_destroy(connection->m_peer);
514 delete connection;
515 m_error = err;
516 return NULL;
517 }
518
519 ioctlsocket(connection->m_fd, FIONBIO, (u_long FAR *) &arg);
520 gs_gui_functions->Enable_Events(connection);
521
522 return connection;
523 }
524
525 /* GSocket_SetReusable:
526 * Simply sets the m_resuable flag on the socket. GSocket_SetServer will
527 * make the appropriate setsockopt() call.
528 * Implemented as a GSocket function because clients (ie, wxSocketServer)
529 * don't have access to the GSocket struct information.
530 * Returns true if the flag was set correctly, false if an error occurred
531 * (ie, if the parameter was NULL)
532 */
533 bool GSocket::SetReusable()
534 {
535 /* socket must not be null, and must not be in use/already bound */
536 if (this && m_fd == INVALID_SOCKET) {
537 m_reusable = true;
538 return true;
539 }
540 return false;
541 }
542
543 /* GSocket_SetBroadcast:
544 * Simply sets the m_broadcast flag on the socket. GSocket_SetServer will
545 * make the appropriate setsockopt() call.
546 * Implemented as a GSocket function because clients (ie, wxSocketServer)
547 * don't have access to the GSocket struct information.
548 * Returns true if the flag was set correctly, false if an error occurred
549 * (ie, if the parameter was NULL)
550 */
551 bool GSocket::SetBroadcast()
552 {
553 /* socket must not be in use/already bound */
554 if (m_fd == INVALID_SOCKET) {
555 m_broadcast = true;
556 return true;
557 }
558 return false;
559 }
560
561 bool GSocket::DontDoBind()
562 {
563 /* socket must not be in use/already bound */
564 if (m_fd == INVALID_SOCKET) {
565 m_dobind = false;
566 return true;
567 }
568 return false;
569 }
570
571 /* Client specific parts */
572
573 /* GSocket_Connect:
574 * For stream (connection oriented) sockets, GSocket_Connect() tries
575 * to establish a client connection to a server using the peer address
576 * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
577 * connection has been successfully established, or one of the error
578 * codes listed below. Note that for nonblocking sockets, a return
579 * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
580 * request can be completed later; you should use GSocket_Select()
581 * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
582 * corresponding asynchronous events.
583 *
584 * For datagram (non connection oriented) sockets, GSocket_Connect()
585 * just sets the peer address established with GSocket_SetPeer() as
586 * default destination.
587 *
588 * Error codes:
589 * GSOCK_INVSOCK - the socket is in use or not valid.
590 * GSOCK_INVADDR - the peer address has not been established.
591 * GSOCK_TIMEDOUT - timeout, the connection failed.
592 * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
593 * GSOCK_MEMERR - couldn't allocate memory.
594 * GSOCK_IOERR - low-level error.
595 */
596 GSocketError GSocket::Connect(GSocketStream stream)
597 {
598 int ret, err;
599 u_long arg = 1;
600
601 assert(this);
602
603 /* Enable CONNECTION events (needed for nonblocking connections) */
604 m_detected &= ~GSOCK_CONNECTION_FLAG;
605
606 if (m_fd != INVALID_SOCKET)
607 {
608 m_error = GSOCK_INVSOCK;
609 return GSOCK_INVSOCK;
610 }
611
612 if (!m_peer)
613 {
614 m_error = GSOCK_INVADDR;
615 return GSOCK_INVADDR;
616 }
617
618 /* Streamed or dgram socket? */
619 m_stream = (stream == GSOCK_STREAMED);
620 m_server = false;
621 m_establishing = false;
622
623 /* Create the socket */
624 m_fd = socket(m_peer->m_realfamily,
625 m_stream? SOCK_STREAM : SOCK_DGRAM, 0);
626
627 if (m_fd == INVALID_SOCKET)
628 {
629 m_error = GSOCK_IOERR;
630 return GSOCK_IOERR;
631 }
632
633 ioctlsocket(m_fd, FIONBIO, (u_long FAR *) &arg);
634 gs_gui_functions->Enable_Events(this);
635
636 // If the reuse flag is set, use the applicable socket reuse flag
637 if (m_reusable)
638 {
639 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(arg));
640 }
641
642 if (m_initialRecvBufferSize >= 0)
643 setsockopt(m_fd, SOL_SOCKET, SO_RCVBUF, (const char*)&m_initialRecvBufferSize, sizeof(m_initialRecvBufferSize));
644 if (m_initialSendBufferSize >= 0)
645 setsockopt(m_fd, SOL_SOCKET, SO_SNDBUF, (const char*)&m_initialSendBufferSize, sizeof(m_initialSendBufferSize));
646
647 // If a local address has been set, then we need to bind to it before calling connect
648 if (m_local && m_local->m_addr)
649 {
650 bind(m_fd, m_local->m_addr, m_local->m_len);
651 }
652
653 /* Connect it to the peer address, with a timeout (see below) */
654 ret = connect(m_fd, m_peer->m_addr, m_peer->m_len);
655
656 if (ret == SOCKET_ERROR)
657 {
658 err = WSAGetLastError();
659
660 /* If connect failed with EWOULDBLOCK and the GSocket object
661 * is in blocking mode, we select() for the specified timeout
662 * checking for writability to see if the connection request
663 * completes.
664 */
665 if ((err == WSAEWOULDBLOCK) && (!m_non_blocking))
666 {
667 err = Connect_Timeout();
668
669 if (err != GSOCK_NOERROR)
670 {
671 Close();
672 /* m_error is set in _GSocket_Connect_Timeout */
673 }
674
675 return (GSocketError) err;
676 }
677
678 /* If connect failed with EWOULDBLOCK and the GSocket object
679 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
680 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
681 * this way if the connection completes, a GSOCK_CONNECTION
682 * event will be generated, if enabled.
683 */
684 if ((err == WSAEWOULDBLOCK) && (m_non_blocking))
685 {
686 m_establishing = true;
687 m_error = GSOCK_WOULDBLOCK;
688 return GSOCK_WOULDBLOCK;
689 }
690
691 /* If connect failed with an error other than EWOULDBLOCK,
692 * then the call to GSocket_Connect() has failed.
693 */
694 Close();
695 m_error = GSOCK_IOERR;
696 return GSOCK_IOERR;
697 }
698
699 return GSOCK_NOERROR;
700 }
701
702 /* Datagram sockets */
703
704 /* GSocket_SetNonOriented:
705 * Sets up this socket as a non-connection oriented (datagram) socket.
706 * Before using this function, the local address must have been set
707 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
708 * on success, or one of the following otherwise.
709 *
710 * Error codes:
711 * GSOCK_INVSOCK - the socket is in use.
712 * GSOCK_INVADDR - the local address has not been set.
713 * GSOCK_IOERR - low-level error.
714 */
715 GSocketError GSocket::SetNonOriented()
716 {
717 u_long arg = 1;
718
719 assert(this);
720
721 if (m_fd != INVALID_SOCKET)
722 {
723 m_error = GSOCK_INVSOCK;
724 return GSOCK_INVSOCK;
725 }
726
727 if (!m_local)
728 {
729 m_error = GSOCK_INVADDR;
730 return GSOCK_INVADDR;
731 }
732
733 /* Initialize all fields */
734 m_stream = false;
735 m_server = false;
736
737 /* Create the socket */
738 m_fd = socket(m_local->m_realfamily, SOCK_DGRAM, 0);
739
740 if (m_fd == INVALID_SOCKET)
741 {
742 m_error = GSOCK_IOERR;
743 return GSOCK_IOERR;
744 }
745
746 ioctlsocket(m_fd, FIONBIO, (u_long FAR *) &arg);
747 gs_gui_functions->Enable_Events(this);
748
749 if (m_reusable)
750 {
751 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(arg));
752 }
753 if (m_broadcast)
754 {
755 setsockopt(m_fd, SOL_SOCKET, SO_BROADCAST, (const char*)&arg, sizeof(arg));
756 }
757 if (m_dobind)
758 {
759 /* Bind to the local address,
760 * and retrieve the actual address bound.
761 */
762 if ((bind(m_fd, m_local->m_addr, m_local->m_len) != 0) ||
763 (getsockname(m_fd,
764 m_local->m_addr,
765 (WX_SOCKLEN_T *)&m_local->m_len) != 0))
766 {
767 Close();
768 m_error = GSOCK_IOERR;
769 return GSOCK_IOERR;
770 }
771 }
772
773 return GSOCK_NOERROR;
774 }
775
776 /* Generic IO */
777
778 /* Like recv(), send(), ... */
779 int GSocket::Read(char *buffer, int size)
780 {
781 int ret;
782
783 assert(this);
784
785 /* Reenable INPUT events */
786 m_detected &= ~GSOCK_INPUT_FLAG;
787
788 if (m_fd == INVALID_SOCKET || m_server)
789 {
790 m_error = GSOCK_INVSOCK;
791 return -1;
792 }
793
794 /* If the socket is blocking, wait for data (with a timeout) */
795 if (Input_Timeout() == GSOCK_TIMEDOUT)
796 {
797 m_error = GSOCK_TIMEDOUT;
798 return -1;
799 }
800
801 /* Read the data */
802 if (m_stream)
803 ret = Recv_Stream(buffer, size);
804 else
805 ret = Recv_Dgram(buffer, size);
806
807 if (ret == SOCKET_ERROR)
808 {
809 if (WSAGetLastError() != WSAEWOULDBLOCK)
810 m_error = GSOCK_IOERR;
811 else
812 m_error = GSOCK_WOULDBLOCK;
813 return -1;
814 }
815
816 return ret;
817 }
818
819 int GSocket::Write(const char *buffer, int size)
820 {
821 int ret;
822
823 assert(this);
824
825 if (m_fd == INVALID_SOCKET || m_server)
826 {
827 m_error = GSOCK_INVSOCK;
828 return -1;
829 }
830
831 /* If the socket is blocking, wait for writability (with a timeout) */
832 if (Output_Timeout() == GSOCK_TIMEDOUT)
833 return -1;
834
835 /* Write the data */
836 if (m_stream)
837 ret = Send_Stream(buffer, size);
838 else
839 ret = Send_Dgram(buffer, size);
840
841 if (ret == SOCKET_ERROR)
842 {
843 if (WSAGetLastError() != WSAEWOULDBLOCK)
844 m_error = GSOCK_IOERR;
845 else
846 m_error = GSOCK_WOULDBLOCK;
847
848 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
849 * does). Once the first OUTPUT event is received, users can assume
850 * that the socket is writable until a read operation fails. Only then
851 * will further OUTPUT events be posted.
852 */
853 m_detected &= ~GSOCK_OUTPUT_FLAG;
854 return -1;
855 }
856
857 return ret;
858 }
859
860 /* GSocket_Select:
861 * Polls the socket to determine its status. This function will
862 * check for the events specified in the 'flags' parameter, and
863 * it will return a mask indicating which operations can be
864 * performed. This function won't block, regardless of the
865 * mode (blocking | nonblocking) of the socket.
866 */
867 GSocketEventFlags GSocket::Select(GSocketEventFlags flags)
868 {
869 if (!gs_gui_functions->CanUseEventLoop())
870 {
871 GSocketEventFlags result = 0;
872 fd_set readfds;
873 fd_set writefds;
874 fd_set exceptfds;
875
876 assert(this);
877
878 FD_ZERO(&readfds);
879 FD_ZERO(&writefds);
880 FD_ZERO(&exceptfds);
881 FD_SET(m_fd, &readfds);
882 if (flags & GSOCK_OUTPUT_FLAG || flags & GSOCK_CONNECTION_FLAG)
883 FD_SET(m_fd, &writefds);
884 FD_SET(m_fd, &exceptfds);
885
886 /* Check 'sticky' CONNECTION flag first */
887 result |= (GSOCK_CONNECTION_FLAG & m_detected);
888
889 /* If we have already detected a LOST event, then don't try
890 * to do any further processing.
891 */
892 if ((m_detected & GSOCK_LOST_FLAG) != 0)
893 {
894 m_establishing = false;
895
896 return (GSOCK_LOST_FLAG & flags);
897 }
898
899 /* Try select now */
900 if (select(m_fd + 1, &readfds, &writefds, &exceptfds,
901 &m_timeout) <= 0)
902 {
903 /* What to do here? */
904 return (result & flags);
905 }
906
907 /* Check for exceptions and errors */
908 if (FD_ISSET(m_fd, &exceptfds))
909 {
910 m_establishing = false;
911 m_detected = GSOCK_LOST_FLAG;
912
913 /* LOST event: Abort any further processing */
914 return (GSOCK_LOST_FLAG & flags);
915 }
916
917 /* Check for readability */
918 if (FD_ISSET(m_fd, &readfds))
919 {
920 result |= GSOCK_INPUT_FLAG;
921
922 if (m_server && m_stream)
923 {
924 /* This is a TCP server socket that detected a connection.
925 While the INPUT_FLAG is also set, it doesn't matter on
926 this kind of sockets, as we can only Accept() from them. */
927 result |= GSOCK_CONNECTION_FLAG;
928 m_detected |= GSOCK_CONNECTION_FLAG;
929 }
930 }
931
932 /* Check for writability */
933 if (FD_ISSET(m_fd, &writefds))
934 {
935 if (m_establishing && !m_server)
936 {
937 int error;
938 WX_SOCKLEN_T len = sizeof(error);
939
940 m_establishing = false;
941
942 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
943
944 if (error)
945 {
946 m_detected = GSOCK_LOST_FLAG;
947
948 /* LOST event: Abort any further processing */
949 return (GSOCK_LOST_FLAG & flags);
950 }
951 else
952 {
953 result |= GSOCK_CONNECTION_FLAG;
954 m_detected |= GSOCK_CONNECTION_FLAG;
955 }
956 }
957 else
958 {
959 result |= GSOCK_OUTPUT_FLAG;
960 }
961 }
962
963 return (result & flags);
964 }
965 else /* USE_GUI() */
966 {
967 assert(this);
968 return flags & m_detected;
969 }
970 }
971
972 /* Attributes */
973
974 /* GSocket_SetNonBlocking:
975 * Sets the socket to non-blocking mode. All IO calls will return
976 * immediately.
977 */
978 void GSocket::SetNonBlocking(bool non_block)
979 {
980 assert(this);
981
982 m_non_blocking = non_block;
983 }
984
985 /* GSocket_SetTimeout:
986 * Sets the timeout for blocking calls. Time is expressed in
987 * milliseconds.
988 */
989 void GSocket::SetTimeout(unsigned long millis)
990 {
991 assert(this);
992
993 m_timeout.tv_sec = (millis / 1000);
994 m_timeout.tv_usec = (millis % 1000) * 1000;
995 }
996
997 /* GSocket_GetError:
998 * Returns the last error occurred for this socket. Note that successful
999 * operations do not clear this back to GSOCK_NOERROR, so use it only
1000 * after an error.
1001 */
1002 GSocketError WXDLLIMPEXP_NET GSocket::GetError()
1003 {
1004 assert(this);
1005
1006 return m_error;
1007 }
1008
1009 /* Callbacks */
1010
1011 /* GSOCK_INPUT:
1012 * There is data to be read in the input buffer. If, after a read
1013 * operation, there is still data available, the callback function will
1014 * be called again.
1015 * GSOCK_OUTPUT:
1016 * The socket is available for writing. That is, the next write call
1017 * won't block. This event is generated only once, when the connection is
1018 * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
1019 * when the output buffer empties again. This means that the app should
1020 * assume that it can write since the first OUTPUT event, and no more
1021 * OUTPUT events will be generated unless an error occurs.
1022 * GSOCK_CONNECTION:
1023 * Connection successfully established, for client sockets, or incoming
1024 * client connection, for server sockets. Wait for this event (also watch
1025 * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
1026 * GSOCK_LOST:
1027 * The connection is lost (or a connection request failed); this could
1028 * be due to a failure, or due to the peer closing it gracefully.
1029 */
1030
1031 /* GSocket_SetCallback:
1032 * Enables the callbacks specified by 'flags'. Note that 'flags'
1033 * may be a combination of flags OR'ed toghether, so the same
1034 * callback function can be made to accept different events.
1035 * The callback function must have the following prototype:
1036 *
1037 * void function(GSocket *socket, GSocketEvent event, char *cdata)
1038 */
1039 void GSocket::SetCallback(GSocketEventFlags flags,
1040 GSocketCallback callback, char *cdata)
1041 {
1042 int count;
1043
1044 assert(this);
1045
1046 for (count = 0; count < GSOCK_MAX_EVENT; count++)
1047 {
1048 if ((flags & (1 << count)) != 0)
1049 {
1050 m_cbacks[count] = callback;
1051 m_data[count] = cdata;
1052 }
1053 }
1054 }
1055
1056 /* GSocket_UnsetCallback:
1057 * Disables all callbacks specified by 'flags', which may be a
1058 * combination of flags OR'ed toghether.
1059 */
1060 void GSocket::UnsetCallback(GSocketEventFlags flags)
1061 {
1062 int count;
1063
1064 assert(this);
1065
1066 for (count = 0; count < GSOCK_MAX_EVENT; count++)
1067 {
1068 if ((flags & (1 << count)) != 0)
1069 {
1070 m_cbacks[count] = NULL;
1071 m_data[count] = NULL;
1072 }
1073 }
1074 }
1075
1076 GSocketError GSocket::GetSockOpt(int level, int optname,
1077 void *optval, int *optlen)
1078 {
1079 if (getsockopt(m_fd, level, optname, (char*)optval, optlen) == 0)
1080 {
1081 return GSOCK_NOERROR;
1082 }
1083 return GSOCK_OPTERR;
1084 }
1085
1086 GSocketError GSocket::SetSockOpt(int level, int optname,
1087 const void *optval, int optlen)
1088 {
1089 if (setsockopt(m_fd, level, optname, (char*)optval, optlen) == 0)
1090 {
1091 return GSOCK_NOERROR;
1092 }
1093 return GSOCK_OPTERR;
1094 }
1095
1096 /* Internals (IO) */
1097
1098 /* _GSocket_Input_Timeout:
1099 * For blocking sockets, wait until data is available or
1100 * until timeout ellapses.
1101 */
1102 GSocketError GSocket::Input_Timeout()
1103 {
1104 fd_set readfds;
1105
1106 if (!m_non_blocking)
1107 {
1108 FD_ZERO(&readfds);
1109 FD_SET(m_fd, &readfds);
1110 if (select(0, &readfds, NULL, NULL, &m_timeout) == 0)
1111 {
1112 m_error = GSOCK_TIMEDOUT;
1113 return GSOCK_TIMEDOUT;
1114 }
1115 }
1116 return GSOCK_NOERROR;
1117 }
1118
1119 /* _GSocket_Output_Timeout:
1120 * For blocking sockets, wait until data can be sent without
1121 * blocking or until timeout ellapses.
1122 */
1123 GSocketError GSocket::Output_Timeout()
1124 {
1125 fd_set writefds;
1126
1127 if (!m_non_blocking)
1128 {
1129 FD_ZERO(&writefds);
1130 FD_SET(m_fd, &writefds);
1131 if (select(0, NULL, &writefds, NULL, &m_timeout) == 0)
1132 {
1133 m_error = GSOCK_TIMEDOUT;
1134 return GSOCK_TIMEDOUT;
1135 }
1136 }
1137 return GSOCK_NOERROR;
1138 }
1139
1140 /* _GSocket_Connect_Timeout:
1141 * For blocking sockets, wait until the connection is
1142 * established or fails, or until timeout ellapses.
1143 */
1144 GSocketError GSocket::Connect_Timeout()
1145 {
1146 fd_set writefds;
1147 fd_set exceptfds;
1148
1149 FD_ZERO(&writefds);
1150 FD_ZERO(&exceptfds);
1151 FD_SET(m_fd, &writefds);
1152 FD_SET(m_fd, &exceptfds);
1153 if (select(0, NULL, &writefds, &exceptfds, &m_timeout) == 0)
1154 {
1155 m_error = GSOCK_TIMEDOUT;
1156 return GSOCK_TIMEDOUT;
1157 }
1158 if (!FD_ISSET(m_fd, &writefds))
1159 {
1160 m_error = GSOCK_IOERR;
1161 return GSOCK_IOERR;
1162 }
1163
1164 return GSOCK_NOERROR;
1165 }
1166
1167 int GSocket::Recv_Stream(char *buffer, int size)
1168 {
1169 return recv(m_fd, buffer, size, 0);
1170 }
1171
1172 int GSocket::Recv_Dgram(char *buffer, int size)
1173 {
1174 wxSockAddr from;
1175 WX_SOCKLEN_T fromlen = sizeof(from);
1176 int ret;
1177 GSocketError err;
1178
1179 ret = recvfrom(m_fd, buffer, size, 0, (sockaddr*)&from, &fromlen);
1180
1181 if (ret == SOCKET_ERROR)
1182 return SOCKET_ERROR;
1183
1184 /* Translate a system address into a GSocket address */
1185 if (!m_peer)
1186 {
1187 m_peer = GAddress_new();
1188 if (!m_peer)
1189 {
1190 m_error = GSOCK_MEMERR;
1191 return -1;
1192 }
1193 }
1194 err = _GAddress_translate_from(m_peer, (sockaddr*)&from, fromlen);
1195 if (err != GSOCK_NOERROR)
1196 {
1197 GAddress_destroy(m_peer);
1198 m_peer = NULL;
1199 m_error = err;
1200 return -1;
1201 }
1202
1203 return ret;
1204 }
1205
1206 int GSocket::Send_Stream(const char *buffer, int size)
1207 {
1208 return send(m_fd, buffer, size, 0);
1209 }
1210
1211 int GSocket::Send_Dgram(const char *buffer, int size)
1212 {
1213 struct sockaddr *addr;
1214 int len, ret;
1215 GSocketError err;
1216
1217 if (!m_peer)
1218 {
1219 m_error = GSOCK_INVADDR;
1220 return -1;
1221 }
1222
1223 err = _GAddress_translate_to(m_peer, &addr, &len);
1224 if (err != GSOCK_NOERROR)
1225 {
1226 m_error = err;
1227 return -1;
1228 }
1229
1230 ret = sendto(m_fd, buffer, size, 0, addr, len);
1231
1232 /* Frees memory allocated by _GAddress_translate_to */
1233 free(addr);
1234
1235 return ret;
1236 }
1237
1238 /* Compatibility functions for GSocket */
1239 GSocket *GSocket_new(void)
1240 {
1241 GSocket *newsocket = new GSocket();
1242 if(newsocket->IsOk())
1243 return newsocket;
1244 delete newsocket;
1245 return NULL;
1246 }
1247
1248
1249 /*
1250 * -------------------------------------------------------------------------
1251 * GAddress
1252 * -------------------------------------------------------------------------
1253 */
1254
1255 /* CHECK_ADDRESS verifies that the current address family is either
1256 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1257 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1258 * an appropiate error code.
1259 *
1260 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
1261 */
1262 #define CHECK_ADDRESS(address, family) \
1263 { \
1264 if (address->m_family == GSOCK_NOFAMILY) \
1265 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1266 return address->m_error; \
1267 if (address->m_family != GSOCK_##family) \
1268 { \
1269 address->m_error = GSOCK_INVADDR; \
1270 return GSOCK_INVADDR; \
1271 } \
1272 }
1273
1274 #define CHECK_ADDRESS_RETVAL(address, family, retval) \
1275 { \
1276 if (address->m_family == GSOCK_NOFAMILY) \
1277 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1278 return retval; \
1279 if (address->m_family != GSOCK_##family) \
1280 { \
1281 address->m_error = GSOCK_INVADDR; \
1282 return retval; \
1283 } \
1284 }
1285
1286
1287 GAddress *GAddress_new(void)
1288 {
1289 GAddress *address;
1290
1291 if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1292 return NULL;
1293
1294 address->m_family = GSOCK_NOFAMILY;
1295 address->m_addr = NULL;
1296 address->m_len = 0;
1297
1298 return address;
1299 }
1300
1301 GAddress *GAddress_copy(GAddress *address)
1302 {
1303 GAddress *addr2;
1304
1305 assert(address != NULL);
1306
1307 if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1308 return NULL;
1309
1310 memcpy(addr2, address, sizeof(GAddress));
1311
1312 if (address->m_addr)
1313 {
1314 addr2->m_addr = (struct sockaddr *) malloc(addr2->m_len);
1315 if (addr2->m_addr == NULL)
1316 {
1317 free(addr2);
1318 return NULL;
1319 }
1320 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
1321 }
1322
1323 return addr2;
1324 }
1325
1326 void GAddress_destroy(GAddress *address)
1327 {
1328 assert(address != NULL);
1329
1330 if (address->m_addr)
1331 free(address->m_addr);
1332
1333 free(address);
1334 }
1335
1336 void GAddress_SetFamily(GAddress *address, GAddressType type)
1337 {
1338 assert(address != NULL);
1339
1340 address->m_family = type;
1341 }
1342
1343 GAddressType GAddress_GetFamily(GAddress *address)
1344 {
1345 assert(address != NULL);
1346
1347 return address->m_family;
1348 }
1349
1350 GSocketError _GAddress_translate_from(GAddress *address,
1351 struct sockaddr *addr, int len)
1352 {
1353 address->m_realfamily = addr->sa_family;
1354 switch (addr->sa_family)
1355 {
1356 case AF_INET:
1357 address->m_family = GSOCK_INET;
1358 break;
1359 case AF_UNIX:
1360 address->m_family = GSOCK_UNIX;
1361 break;
1362 #if wxUSE_IPV6
1363 case AF_INET6:
1364 address->m_family = GSOCK_INET6;
1365 break;
1366 #endif
1367 default:
1368 {
1369 address->m_error = GSOCK_INVOP;
1370 return GSOCK_INVOP;
1371 }
1372 }
1373
1374 if (address->m_addr)
1375 free(address->m_addr);
1376
1377 address->m_len = len;
1378 address->m_addr = (struct sockaddr *) malloc(len);
1379
1380 if (address->m_addr == NULL)
1381 {
1382 address->m_error = GSOCK_MEMERR;
1383 return GSOCK_MEMERR;
1384 }
1385 memcpy(address->m_addr, addr, len);
1386
1387 return GSOCK_NOERROR;
1388 }
1389
1390 GSocketError _GAddress_translate_to(GAddress *address,
1391 struct sockaddr **addr, int *len)
1392 {
1393 if (!address->m_addr)
1394 {
1395 address->m_error = GSOCK_INVADDR;
1396 return GSOCK_INVADDR;
1397 }
1398
1399 *len = address->m_len;
1400 *addr = (struct sockaddr *) malloc(address->m_len);
1401 if (*addr == NULL)
1402 {
1403 address->m_error = GSOCK_MEMERR;
1404 return GSOCK_MEMERR;
1405 }
1406
1407 memcpy(*addr, address->m_addr, address->m_len);
1408 return GSOCK_NOERROR;
1409 }
1410
1411 /*
1412 * -------------------------------------------------------------------------
1413 * Internet address family
1414 * -------------------------------------------------------------------------
1415 */
1416
1417 GSocketError _GAddress_Init_INET(GAddress *address)
1418 {
1419 address->m_len = sizeof(struct sockaddr_in);
1420 address->m_addr = (struct sockaddr *) malloc(address->m_len);
1421 if (address->m_addr == NULL)
1422 {
1423 address->m_error = GSOCK_MEMERR;
1424 return GSOCK_MEMERR;
1425 }
1426
1427 address->m_family = GSOCK_INET;
1428 address->m_realfamily = AF_INET;
1429 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
1430 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
1431
1432 return GSOCK_NOERROR;
1433 }
1434
1435 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
1436 {
1437 struct hostent *he;
1438 struct in_addr *addr;
1439
1440 assert(address != NULL);
1441
1442 CHECK_ADDRESS(address, INET);
1443
1444 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1445
1446 addr->s_addr = inet_addr(hostname);
1447
1448 /* If it is a numeric host name, convert it now */
1449 if (addr->s_addr == INADDR_NONE)
1450 {
1451 struct in_addr *array_addr;
1452
1453 /* It is a real name, we solve it */
1454 if ((he = gethostbyname(hostname)) == NULL)
1455 {
1456 /* addr->s_addr = INADDR_NONE just done by inet_addr() above */
1457 address->m_error = GSOCK_NOHOST;
1458 return GSOCK_NOHOST;
1459 }
1460 array_addr = (struct in_addr *) *(he->h_addr_list);
1461 addr->s_addr = array_addr[0].s_addr;
1462 }
1463 return GSOCK_NOERROR;
1464 }
1465
1466 GSocketError GAddress_INET_SetBroadcastAddress(GAddress *address)
1467 {
1468 return GAddress_INET_SetHostAddress(address, INADDR_BROADCAST);
1469 }
1470
1471 GSocketError GAddress_INET_SetAnyAddress(GAddress *address)
1472 {
1473 return GAddress_INET_SetHostAddress(address, INADDR_ANY);
1474 }
1475
1476 GSocketError GAddress_INET_SetHostAddress(GAddress *address,
1477 unsigned long hostaddr)
1478 {
1479 struct in_addr *addr;
1480
1481 assert(address != NULL);
1482
1483 CHECK_ADDRESS(address, INET);
1484
1485 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1486 addr->s_addr = htonl(hostaddr);
1487
1488 return GSOCK_NOERROR;
1489 }
1490
1491 GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
1492 const char *protocol)
1493 {
1494 struct servent *se;
1495 struct sockaddr_in *addr;
1496
1497 assert(address != NULL);
1498 CHECK_ADDRESS(address, INET);
1499
1500 if (!port)
1501 {
1502 address->m_error = GSOCK_INVPORT;
1503 return GSOCK_INVPORT;
1504 }
1505
1506 se = getservbyname(port, protocol);
1507 if (!se)
1508 {
1509 if (isdigit(port[0]))
1510 {
1511 int port_int;
1512
1513 port_int = atoi(port);
1514 addr = (struct sockaddr_in *)address->m_addr;
1515 addr->sin_port = htons((u_short) port_int);
1516 return GSOCK_NOERROR;
1517 }
1518
1519 address->m_error = GSOCK_INVPORT;
1520 return GSOCK_INVPORT;
1521 }
1522
1523 addr = (struct sockaddr_in *)address->m_addr;
1524 addr->sin_port = se->s_port;
1525
1526 return GSOCK_NOERROR;
1527 }
1528
1529 GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
1530 {
1531 struct sockaddr_in *addr;
1532
1533 assert(address != NULL);
1534 CHECK_ADDRESS(address, INET);
1535
1536 addr = (struct sockaddr_in *)address->m_addr;
1537 addr->sin_port = htons(port);
1538
1539 return GSOCK_NOERROR;
1540 }
1541
1542 GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1543 {
1544 struct hostent *he;
1545 char *addr_buf;
1546 struct sockaddr_in *addr;
1547
1548 assert(address != NULL);
1549 CHECK_ADDRESS(address, INET);
1550
1551 addr = (struct sockaddr_in *)address->m_addr;
1552 addr_buf = (char *)&(addr->sin_addr);
1553
1554 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
1555 if (he == NULL)
1556 {
1557 address->m_error = GSOCK_NOHOST;
1558 return GSOCK_NOHOST;
1559 }
1560
1561 strncpy(hostname, he->h_name, sbuf);
1562
1563 return GSOCK_NOERROR;
1564 }
1565
1566 unsigned long GAddress_INET_GetHostAddress(GAddress *address)
1567 {
1568 struct sockaddr_in *addr;
1569
1570 assert(address != NULL);
1571 CHECK_ADDRESS_RETVAL(address, INET, 0);
1572
1573 addr = (struct sockaddr_in *)address->m_addr;
1574
1575 return ntohl(addr->sin_addr.s_addr);
1576 }
1577
1578 unsigned short GAddress_INET_GetPort(GAddress *address)
1579 {
1580 struct sockaddr_in *addr;
1581
1582 assert(address != NULL);
1583 CHECK_ADDRESS_RETVAL(address, INET, 0);
1584
1585 addr = (struct sockaddr_in *)address->m_addr;
1586 return ntohs(addr->sin_port);
1587 }
1588
1589
1590 #if wxUSE_IPV6
1591 /*
1592 * -------------------------------------------------------------------------
1593 * Internet IPv6 address family
1594 * -------------------------------------------------------------------------
1595 */
1596 #include "ws2tcpip.h"
1597
1598 #ifdef __VISUALC__
1599 #pragma comment(lib,"ws2_32")
1600 #endif // __VISUALC__
1601
1602 GSocketError _GAddress_Init_INET6(GAddress *address)
1603 {
1604 struct in6_addr any_address = IN6ADDR_ANY_INIT;
1605 address->m_len = sizeof(struct sockaddr_in6);
1606 address->m_addr = (struct sockaddr *) malloc(address->m_len);
1607 if (address->m_addr == NULL)
1608 {
1609 address->m_error = GSOCK_MEMERR;
1610 return GSOCK_MEMERR;
1611 }
1612 memset(address->m_addr,0,address->m_len);
1613
1614 address->m_family = GSOCK_INET6;
1615 address->m_realfamily = AF_INET6;
1616 ((struct sockaddr_in6 *)address->m_addr)->sin6_family = AF_INET6;
1617 ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = any_address;
1618
1619 return GSOCK_NOERROR;
1620 }
1621
1622 GSocketError GAddress_INET6_SetHostName(GAddress *address, const char *hostname)
1623 {
1624 assert(address != NULL);
1625 CHECK_ADDRESS(address, INET6);
1626
1627 addrinfo hints;
1628 memset( & hints, 0, sizeof( hints ) );
1629 hints.ai_family = AF_INET6;
1630 addrinfo * info = 0;
1631 if ( getaddrinfo( hostname, "0", & hints, & info ) || ! info )
1632 {
1633 address->m_error = GSOCK_NOHOST;
1634 return GSOCK_NOHOST;
1635 }
1636
1637 memcpy( address->m_addr, info->ai_addr, info->ai_addrlen );
1638 freeaddrinfo( info );
1639 return GSOCK_NOERROR;
1640 }
1641
1642 GSocketError GAddress_INET6_SetAnyAddress(GAddress *address)
1643 {
1644 assert(address != NULL);
1645
1646 CHECK_ADDRESS(address, INET6);
1647
1648 struct in6_addr addr;
1649 memset( & addr, 0, sizeof( addr ) );
1650 return GAddress_INET6_SetHostAddress(address, addr);
1651 }
1652 GSocketError GAddress_INET6_SetHostAddress(GAddress *address,
1653 struct in6_addr hostaddr)
1654 {
1655 assert(address != NULL);
1656
1657 CHECK_ADDRESS(address, INET6);
1658
1659 ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = hostaddr;
1660
1661 return GSOCK_NOERROR;
1662 }
1663
1664 GSocketError GAddress_INET6_SetPortName(GAddress *address, const char *port,
1665 const char *protocol)
1666 {
1667 struct servent *se;
1668 struct sockaddr_in6 *addr;
1669
1670 assert(address != NULL);
1671 CHECK_ADDRESS(address, INET6);
1672
1673 if (!port)
1674 {
1675 address->m_error = GSOCK_INVPORT;
1676 return GSOCK_INVPORT;
1677 }
1678
1679 se = getservbyname(port, protocol);
1680 if (!se)
1681 {
1682 if (isdigit(port[0]))
1683 {
1684 int port_int;
1685
1686 port_int = atoi(port);
1687 addr = (struct sockaddr_in6 *)address->m_addr;
1688 addr->sin6_port = htons((u_short) port_int);
1689 return GSOCK_NOERROR;
1690 }
1691
1692 address->m_error = GSOCK_INVPORT;
1693 return GSOCK_INVPORT;
1694 }
1695
1696 addr = (struct sockaddr_in6 *)address->m_addr;
1697 addr->sin6_port = se->s_port;
1698
1699 return GSOCK_NOERROR;
1700 }
1701
1702 GSocketError GAddress_INET6_SetPort(GAddress *address, unsigned short port)
1703 {
1704 struct sockaddr_in6 *addr;
1705
1706 assert(address != NULL);
1707 CHECK_ADDRESS(address, INET6);
1708
1709 addr = (struct sockaddr_in6 *)address->m_addr;
1710 addr->sin6_port = htons(port);
1711
1712 return GSOCK_NOERROR;
1713 }
1714
1715 GSocketError GAddress_INET6_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1716 {
1717 struct hostent *he;
1718 char *addr_buf;
1719 struct sockaddr_in6 *addr;
1720
1721 assert(address != NULL);
1722 CHECK_ADDRESS(address, INET6);
1723
1724 addr = (struct sockaddr_in6 *)address->m_addr;
1725 addr_buf = (char *)&(addr->sin6_addr);
1726
1727 he = gethostbyaddr(addr_buf, sizeof(addr->sin6_addr), AF_INET6);
1728 if (he == NULL)
1729 {
1730 address->m_error = GSOCK_NOHOST;
1731 return GSOCK_NOHOST;
1732 }
1733
1734 strncpy(hostname, he->h_name, sbuf);
1735
1736 return GSOCK_NOERROR;
1737 }
1738
1739 GSocketError GAddress_INET6_GetHostAddress(GAddress *address,struct in6_addr *hostaddr)
1740 {
1741 assert(address != NULL);
1742 assert(hostaddr != NULL);
1743 CHECK_ADDRESS_RETVAL(address, INET6, GSOCK_INVADDR);
1744 *hostaddr = ( (struct sockaddr_in6 *)address->m_addr )->sin6_addr;
1745 return GSOCK_NOERROR;
1746 }
1747
1748 unsigned short GAddress_INET6_GetPort(GAddress *address)
1749 {
1750 assert(address != NULL);
1751 CHECK_ADDRESS_RETVAL(address, INET6, 0);
1752
1753 return ntohs( ((struct sockaddr_in6 *)address->m_addr)->sin6_port );
1754 }
1755
1756 #endif // wxUSE_IPV6
1757
1758 /*
1759 * -------------------------------------------------------------------------
1760 * Unix address family
1761 * -------------------------------------------------------------------------
1762 */
1763
1764 GSocketError _GAddress_Init_UNIX(GAddress *address)
1765 {
1766 assert (address != NULL);
1767 address->m_error = GSOCK_INVADDR;
1768 return GSOCK_INVADDR;
1769 }
1770
1771 GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *WXUNUSED(path))
1772 {
1773 assert (address != NULL);
1774 address->m_error = GSOCK_INVADDR;
1775 return GSOCK_INVADDR;
1776 }
1777
1778 GSocketError GAddress_UNIX_GetPath(GAddress *address, char *WXUNUSED(path), size_t WXUNUSED(sbuf))
1779 {
1780 assert (address != NULL);
1781 address->m_error = GSOCK_INVADDR;
1782 return GSOCK_INVADDR;
1783 }
1784
1785 #else /* !wxUSE_SOCKETS */
1786
1787 /*
1788 * Translation unit shouldn't be empty, so include this typedef to make the
1789 * compiler (VC++ 6.0, for example) happy
1790 */
1791 typedef void (*wxDummy)();
1792
1793 #endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */