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