]> git.saurik.com Git - wxWidgets.git/blob - src/unix/gsocket.cpp
77a818bf6daded65c58ee32e9ac02eb46ff2c2e3
[wxWidgets.git] / src / unix / gsocket.cpp
1 /* -------------------------------------------------------------------------
2 * Project: GSocket (Generic Socket) for WX
3 * Name: gsocket.c
4 * Copyright: (c) Guilhem Lavaux
5 * Licence: wxWindows Licence
6 * Authors: David Elliott (C++ conversion, maintainer)
7 * Guilhem Lavaux,
8 * Guillermo Rodriguez Garcia <guille@iies.es>
9 * Purpose: GSocket main Unix and OS/2 file
10 * Licence: The wxWindows licence
11 * CVSID: $Id$
12 * -------------------------------------------------------------------------
13 */
14
15 #include "wx/wxprec.h"
16
17 #if wxUSE_SOCKETS
18
19 #include "wx/gsocket.h"
20
21 #include "wx/private/fd.h"
22 #include "wx/private/socket.h"
23 #include "wx/private/gsocketiohandler.h"
24
25 #if defined(__VISAGECPP__)
26 #define BSD_SELECT /* use Berkeley Sockets select */
27 #endif
28
29 #if defined(__WATCOMC__)
30 #include <errno.h>
31 #include <nerrno.h>
32 #endif
33
34 #include <assert.h>
35 #include <sys/types.h>
36 #ifdef __VISAGECPP__
37 #include <string.h>
38 #include <sys/time.h>
39 #include <types.h>
40 #include <netinet/in.h>
41 #endif
42 #include <netdb.h>
43 #include <sys/ioctl.h>
44
45 #ifdef HAVE_SYS_SELECT_H
46 # include <sys/select.h>
47 #endif
48
49 #ifdef __VMS__
50 #include <socket.h>
51 struct sockaddr_un
52 {
53 u_char sun_len; /* sockaddr len including null */
54 u_char sun_family; /* AF_UNIX */
55 char sun_path[108]; /* path name (gag) */
56 };
57 #else
58 #include <sys/socket.h>
59 #include <sys/un.h>
60 #endif
61
62 #ifndef __VISAGECPP__
63 #include <sys/time.h>
64 #include <netinet/in.h>
65 #include <arpa/inet.h>
66 #include <errno.h>
67 #include <string.h>
68 #include <unistd.h>
69 #else
70 #include <nerrno.h>
71 # if __IBMCPP__ < 400
72 #include <machine/endian.h>
73 #include <socket.h>
74 #include <ioctl.h>
75 #include <select.h>
76 #include <unistd.h>
77
78 #define EBADF SOCEBADF
79
80 # ifdef min
81 # undef min
82 # endif
83 # else
84 #include <sys/socket.h>
85 #include <sys/ioctl.h>
86 #include <sys/select.h>
87
88 #define close(a) soclose(a)
89 #define select(a,b,c,d,e) bsdselect(a,b,c,d,e)
90 int _System bsdselect(int,
91 struct fd_set *,
92 struct fd_set *,
93 struct fd_set *,
94 struct timeval *);
95 int _System soclose(int);
96 # endif
97 #endif
98 #ifdef __EMX__
99 #include <sys/select.h>
100 #endif
101
102 #include <stdio.h>
103 #include <stdlib.h>
104 #include <stddef.h>
105 #include <ctype.h>
106 #ifdef sun
107 # include <sys/filio.h>
108 #endif
109 #ifdef sgi
110 # include <bstring.h>
111 #endif
112 #ifdef _AIX
113 # include <strings.h>
114 #endif
115 #include <signal.h>
116
117 #ifndef WX_SOCKLEN_T
118
119 #ifdef VMS
120 # define WX_SOCKLEN_T unsigned int
121 #else
122 # ifdef __GLIBC__
123 # if __GLIBC__ == 2
124 # define WX_SOCKLEN_T socklen_t
125 # endif
126 # elif defined(__WXMAC__)
127 # define WX_SOCKLEN_T socklen_t
128 # else
129 # define WX_SOCKLEN_T int
130 # endif
131 #endif
132
133 #endif /* SOCKLEN_T */
134
135 #ifndef SOCKOPTLEN_T
136 #define SOCKOPTLEN_T WX_SOCKLEN_T
137 #endif
138
139 /* UnixWare reportedly needs this for FIONBIO definition */
140 #ifdef __UNIXWARE__
141 #include <sys/filio.h>
142 #endif
143
144 /*
145 * INADDR_BROADCAST is identical to INADDR_NONE which is not defined
146 * on all systems. INADDR_BROADCAST should be fine to indicate an error.
147 */
148 #ifndef INADDR_NONE
149 #define INADDR_NONE INADDR_BROADCAST
150 #endif
151
152 #if defined(__VISAGECPP__) || defined(__WATCOMC__)
153
154 #define MASK_SIGNAL() {
155 #define UNMASK_SIGNAL() }
156
157 #else
158 extern "C" { typedef void (*wxSigHandler)(int); }
159
160 #define MASK_SIGNAL() \
161 { \
162 wxSigHandler old_handler = signal(SIGPIPE, SIG_IGN);
163
164 #define UNMASK_SIGNAL() \
165 signal(SIGPIPE, old_handler); \
166 }
167
168 #endif
169
170 /* If a SIGPIPE is issued by a socket call on a remotely closed socket,
171 the program will "crash" unless it explicitly handles the SIGPIPE.
172 By using MSG_NOSIGNAL, the SIGPIPE is suppressed. Later, we will
173 use SO_NOSIGPIPE (if available), the BSD equivalent. */
174 #ifdef MSG_NOSIGNAL
175 # define GSOCKET_MSG_NOSIGNAL MSG_NOSIGNAL
176 #else /* MSG_NOSIGNAL not available (FreeBSD including OS X) */
177 # define GSOCKET_MSG_NOSIGNAL 0
178 #endif /* MSG_NOSIGNAL */
179
180 #if wxUSE_THREADS && (defined(HAVE_GETHOSTBYNAME) || defined(HAVE_GETSERVBYNAME))
181 # include "wx/thread.h"
182 #endif
183
184 #if defined(HAVE_GETHOSTBYNAME)
185 static struct hostent * deepCopyHostent(struct hostent *h,
186 const struct hostent *he,
187 char *buffer, int size, int *err)
188 {
189 /* copy old structure */
190 memcpy(h, he, sizeof(struct hostent));
191
192 /* copy name */
193 int len = strlen(h->h_name);
194 if (len > size)
195 {
196 *err = ENOMEM;
197 return NULL;
198 }
199 memcpy(buffer, h->h_name, len);
200 buffer[len] = '\0';
201 h->h_name = buffer;
202
203 /* track position in the buffer */
204 int pos = len + 1;
205
206 /* reuse len to store address length */
207 len = h->h_length;
208
209 /* ensure pointer alignment */
210 unsigned int misalign = sizeof(char *) - pos%sizeof(char *);
211 if(misalign < sizeof(char *))
212 pos += misalign;
213
214 /* leave space for pointer list */
215 char **p = h->h_addr_list, **q;
216 char **h_addr_list = (char **)(buffer + pos);
217 while(*(p++) != 0)
218 pos += sizeof(char *);
219
220 /* copy addresses and fill new pointer list */
221 for (p = h->h_addr_list, q = h_addr_list; *p != 0; p++, q++)
222 {
223 if (size < pos + len)
224 {
225 *err = ENOMEM;
226 return NULL;
227 }
228 memcpy(buffer + pos, *p, len); /* copy content */
229 *q = buffer + pos; /* set copied pointer to copied content */
230 pos += len;
231 }
232 *++q = 0; /* null terminate the pointer list */
233 h->h_addr_list = h_addr_list; /* copy pointer to pointers */
234
235 /* ensure word alignment of pointers */
236 misalign = sizeof(char *) - pos%sizeof(char *);
237 if(misalign < sizeof(char *))
238 pos += misalign;
239
240 /* leave space for pointer list */
241 p = h->h_aliases;
242 char **h_aliases = (char **)(buffer + pos);
243 while(*(p++) != 0)
244 pos += sizeof(char *);
245
246 /* copy aliases and fill new pointer list */
247 for (p = h->h_aliases, q = h_aliases; *p != 0; p++, q++)
248 {
249 len = strlen(*p);
250 if (size <= pos + len)
251 {
252 *err = ENOMEM;
253 return NULL;
254 }
255 memcpy(buffer + pos, *p, len); /* copy content */
256 buffer[pos + len] = '\0';
257 *q = buffer + pos; /* set copied pointer to copied content */
258 pos += len + 1;
259 }
260 *++q = 0; /* null terminate the pointer list */
261 h->h_aliases = h_aliases; /* copy pointer to pointers */
262
263 return h;
264 }
265 #endif
266
267 #if defined(HAVE_GETHOSTBYNAME) && wxUSE_THREADS
268 static wxMutex nameLock;
269 #endif
270 struct hostent * wxGethostbyname_r(const char *hostname, struct hostent *h,
271 void *buffer, int size, int *err)
272
273 {
274 struct hostent *he = NULL;
275 *err = 0;
276 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_6)
277 if (gethostbyname_r(hostname, h, (char*)buffer, size, &he, err))
278 he = NULL;
279 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
280 he = gethostbyname_r(hostname, h, (char*)buffer, size, err);
281 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
282 if (gethostbyname_r(hostname, h, (struct hostent_data*) buffer))
283 {
284 he = NULL;
285 *err = h_errno;
286 }
287 else
288 he = h;
289 #elif defined(HAVE_GETHOSTBYNAME)
290 #if wxUSE_THREADS
291 wxMutexLocker locker(nameLock);
292 #endif
293 he = gethostbyname(hostname);
294 if (!he)
295 *err = h_errno;
296 else
297 he = deepCopyHostent(h, he, (char*)buffer, size, err);
298 #endif
299 return he;
300 }
301
302 #if defined(HAVE_GETHOSTBYNAME) && wxUSE_THREADS
303 static wxMutex addrLock;
304 #endif
305 struct hostent * wxGethostbyaddr_r(const char *addr_buf, int buf_size,
306 int proto, struct hostent *h,
307 void *buffer, int size, int *err)
308 {
309 struct hostent *he = NULL;
310 *err = 0;
311 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_6)
312 if (gethostbyaddr_r(addr_buf, buf_size, proto, h,
313 (char*)buffer, size, &he, err))
314 he = NULL;
315 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
316 he = gethostbyaddr_r(addr_buf, buf_size, proto, h, (char*)buffer, size, err);
317 #elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
318 if (gethostbyaddr_r(addr_buf, buf_size, proto, h,
319 (struct hostent_data*) buffer))
320 {
321 he = NULL;
322 *err = h_errno;
323 }
324 else
325 he = h;
326 #elif defined(HAVE_GETHOSTBYNAME)
327 #if wxUSE_THREADS
328 wxMutexLocker locker(addrLock);
329 #endif
330 he = gethostbyaddr(addr_buf, buf_size, proto);
331 if (!he)
332 *err = h_errno;
333 else
334 he = deepCopyHostent(h, he, (char*)buffer, size, err);
335 #endif
336 return he;
337 }
338
339 #if defined(HAVE_GETSERVBYNAME)
340 static struct servent * deepCopyServent(struct servent *s,
341 const struct servent *se,
342 char *buffer, int size)
343 {
344 /* copy plain old structure */
345 memcpy(s, se, sizeof(struct servent));
346
347 /* copy name */
348 int len = strlen(s->s_name);
349 if (len >= size)
350 {
351 return NULL;
352 }
353 memcpy(buffer, s->s_name, len);
354 buffer[len] = '\0';
355 s->s_name = buffer;
356
357 /* track position in the buffer */
358 int pos = len + 1;
359
360 /* copy protocol */
361 len = strlen(s->s_proto);
362 if (pos + len >= size)
363 {
364 return NULL;
365 }
366 memcpy(buffer + pos, s->s_proto, len);
367 buffer[pos + len] = '\0';
368 s->s_proto = buffer + pos;
369
370 /* track position in the buffer */
371 pos += len + 1;
372
373 /* ensure pointer alignment */
374 unsigned int misalign = sizeof(char *) - pos%sizeof(char *);
375 if(misalign < sizeof(char *))
376 pos += misalign;
377
378 /* leave space for pointer list */
379 char **p = s->s_aliases, **q;
380 char **s_aliases = (char **)(buffer + pos);
381 while(*(p++) != 0)
382 pos += sizeof(char *);
383
384 /* copy addresses and fill new pointer list */
385 for (p = s->s_aliases, q = s_aliases; *p != 0; p++, q++){
386 len = strlen(*p);
387 if (size <= pos + len)
388 {
389 return NULL;
390 }
391 memcpy(buffer + pos, *p, len); /* copy content */
392 buffer[pos + len] = '\0';
393 *q = buffer + pos; /* set copied pointer to copied content */
394 pos += len + 1;
395 }
396 *++q = 0; /* null terminate the pointer list */
397 s->s_aliases = s_aliases; /* copy pointer to pointers */
398 return s;
399 }
400 #endif
401
402 #if defined(HAVE_GETSERVBYNAME) && wxUSE_THREADS
403 static wxMutex servLock;
404 #endif
405 struct servent *wxGetservbyname_r(const char *port, const char *protocol,
406 struct servent *serv, void *buffer, int size)
407 {
408 struct servent *se = NULL;
409 #if defined(HAVE_FUNC_GETSERVBYNAME_R_6)
410 if (getservbyname_r(port, protocol, serv, (char*)buffer, size, &se))
411 se = NULL;
412 #elif defined(HAVE_FUNC_GETSERVBYNAME_R_5)
413 se = getservbyname_r(port, protocol, serv, (char*)buffer, size);
414 #elif defined(HAVE_FUNC_GETSERVBYNAME_R_4)
415 if (getservbyname_r(port, protocol, serv, (struct servent_data*) buffer))
416 se = NULL;
417 else
418 se = serv;
419 #elif defined(HAVE_GETSERVBYNAME)
420 #if wxUSE_THREADS
421 wxMutexLocker locker(servLock);
422 #endif
423 se = getservbyname(port, protocol);
424 if (se)
425 se = deepCopyServent(serv, se, (char*)buffer, size);
426 #endif
427 return se;
428 }
429
430 /* debugging helpers */
431 #ifdef __GSOCKET_DEBUG__
432 # define GSocket_Debug(args) printf args
433 #else
434 # define GSocket_Debug(args)
435 #endif /* __GSOCKET_DEBUG__ */
436
437 /* Table of GUI-related functions. We must call them indirectly because
438 * of wxBase and GUI separation: */
439
440 bool GSocket_Init()
441 {
442 GSocketManager * const manager = GSocketManager::Get();
443 return manager && manager->OnInit();
444 }
445
446 void GSocket_Cleanup()
447 {
448 GSocketManager * const manager = GSocketManager::Get();
449 if ( manager )
450 manager->OnExit();
451 }
452
453 /* Constructors / Destructors for GSocket */
454
455 GSocket::GSocket(wxSocketBase& wxsocket)
456 : GSocketBase(wxsocket)
457 {
458 m_handler = NULL;
459
460 m_gui_dependent = NULL;
461 m_use_events = false;
462 }
463
464 void GSocket::Close()
465 {
466 if (m_use_events)
467 DisableEvents();
468
469 /* When running on OS X, the gsockosx implementation of GSocketGUIFunctionsTable
470 will close the socket during Disable_Events. However, it will only do this
471 if it is being used. That is, it won't do it in a console program. To
472 ensure we get the right behavior, we have gsockosx set m_fd = INVALID_SOCKET
473 if it has closed the socket which indicates to us (at runtime, instead of
474 at compile time as this had been before) that the socket has already
475 been closed.
476 */
477 if(m_fd != INVALID_SOCKET)
478 close(m_fd);
479 m_fd = INVALID_SOCKET;
480 }
481
482 GSocket::~GSocket()
483 {
484 delete m_handler;
485 }
486
487 /* GSocket_Shutdown:
488 * Disallow further read/write operations on this socket, close
489 * the fd and disable all callbacks.
490 */
491 void GSocket::Shutdown()
492 {
493 /* Don't allow events to fire after socket has been closed */
494 if (m_use_events)
495 DisableEvents();
496
497 GSocketBase::Shutdown();
498 }
499
500 /* Server specific parts */
501
502 /* GSocket_SetServer:
503 * Sets up this socket as a server. The local address must have been
504 * set with GSocket_SetLocal() before GSocket_SetServer() is called.
505 * Returns GSOCK_NOERROR on success, one of the following otherwise:
506 *
507 * Error codes:
508 * GSOCK_INVSOCK - the socket is in use.
509 * GSOCK_INVADDR - the local address has not been set.
510 * GSOCK_IOERR - low-level error.
511 */
512 GSocketError GSocket::SetServer()
513 {
514 int arg = 1;
515
516 assert(this);
517
518 /* must not be in use */
519 if (m_fd != INVALID_SOCKET)
520 {
521 m_error = GSOCK_INVSOCK;
522 return GSOCK_INVSOCK;
523 }
524
525 /* the local addr must have been set */
526 if (!m_local)
527 {
528 m_error = GSOCK_INVADDR;
529 return GSOCK_INVADDR;
530 }
531
532 /* Initialize all fields */
533 m_stream = true;
534 m_server = true;
535
536 /* Create the socket */
537 m_fd = socket(m_local->m_realfamily, SOCK_STREAM, 0);
538
539 if (m_fd == INVALID_SOCKET)
540 {
541 m_error = GSOCK_IOERR;
542 return GSOCK_IOERR;
543 }
544
545 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
546 #ifdef SO_NOSIGPIPE
547 setsockopt(m_fd, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&arg, sizeof(arg));
548 #endif
549
550 ioctl(m_fd, FIONBIO, &arg);
551 if (m_use_events)
552 EnableEvents();
553
554 /* allow a socket to re-bind if the socket is in the TIME_WAIT
555 state after being previously closed.
556 */
557 if (m_reusable)
558 {
559 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(arg));
560 #ifdef SO_REUSEPORT
561 setsockopt(m_fd, SOL_SOCKET, SO_REUSEPORT, (const char*)&arg, sizeof(arg));
562 #endif
563 }
564
565 /* Bind to the local address,
566 * retrieve the actual address bound,
567 * and listen up to 5 connections.
568 */
569 if ((bind(m_fd, m_local->m_addr, m_local->m_len) != 0) ||
570 (getsockname(m_fd,
571 m_local->m_addr,
572 (WX_SOCKLEN_T *) &m_local->m_len) != 0) ||
573 (listen(m_fd, 5) != 0))
574 {
575 Close();
576 m_error = GSOCK_IOERR;
577 return GSOCK_IOERR;
578 }
579
580 return GSOCK_NOERROR;
581 }
582
583 /* GSocket_WaitConnection:
584 * Waits for an incoming client connection. Returns a pointer to
585 * a GSocket object, or NULL if there was an error, in which case
586 * the last error field will be updated for the calling GSocket.
587 *
588 * Error codes (set in the calling GSocket)
589 * GSOCK_INVSOCK - the socket is not valid or not a server.
590 * GSOCK_TIMEDOUT - timeout, no incoming connections.
591 * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
592 * GSOCK_MEMERR - couldn't allocate memory.
593 * GSOCK_IOERR - low-level error.
594 */
595 GSocket *GSocket::WaitConnection(wxSocketBase& wxsocket)
596 {
597 wxSockAddr from;
598 WX_SOCKLEN_T fromlen = sizeof(from);
599 GSocket *connection;
600 GSocketError err;
601 int arg = 1;
602
603 assert(this);
604
605 /* If the socket has already been created, we exit immediately */
606 if (m_fd == INVALID_SOCKET || !m_server)
607 {
608 m_error = GSOCK_INVSOCK;
609 return NULL;
610 }
611
612 /* Create a GSocket object for the new connection */
613 connection = GSocket::Create(wxsocket);
614
615 if (!connection)
616 {
617 m_error = GSOCK_MEMERR;
618 return NULL;
619 }
620
621 /* Wait for a connection (with timeout) */
622 if (Input_Timeout() == GSOCK_TIMEDOUT)
623 {
624 delete connection;
625 /* m_error set by _GSocket_Input_Timeout */
626 return NULL;
627 }
628
629 connection->m_fd = accept(m_fd, (sockaddr*)&from, (WX_SOCKLEN_T *) &fromlen);
630
631 /* Reenable CONNECTION events */
632 Enable(GSOCK_CONNECTION);
633
634 if (connection->m_fd == INVALID_SOCKET)
635 {
636 if (errno == EWOULDBLOCK)
637 m_error = GSOCK_WOULDBLOCK;
638 else
639 m_error = GSOCK_IOERR;
640
641 delete connection;
642 return NULL;
643 }
644
645 /* Initialize all fields */
646 connection->m_server = false;
647 connection->m_stream = true;
648
649 /* Setup the peer address field */
650 connection->m_peer = GAddress_new();
651 if (!connection->m_peer)
652 {
653 delete connection;
654 m_error = GSOCK_MEMERR;
655 return NULL;
656 }
657
658 err = _GAddress_translate_from(connection->m_peer, (sockaddr*)&from, fromlen);
659 if (err != GSOCK_NOERROR)
660 {
661 delete connection;
662 m_error = err;
663 return NULL;
664 }
665
666 #if defined(__EMX__) || defined(__VISAGECPP__)
667 ioctl(connection->m_fd, FIONBIO, (char*)&arg, sizeof(arg));
668 #else
669 ioctl(connection->m_fd, FIONBIO, &arg);
670 #endif
671 if (m_use_events)
672 connection->Notify(true);
673
674 return connection;
675 }
676
677 void GSocket::Notify(bool flag)
678 {
679 if (flag == m_use_events)
680 return;
681 m_use_events = flag;
682 EnableEvents(flag);
683 }
684
685 void GSocket::EnableEvents(bool flag)
686 {
687 if (flag)
688 GSocketManager::Get()->Enable_Events(this);
689 else
690 GSocketManager::Get()->Disable_Events(this);
691 }
692
693 bool GSocket::SetReusable()
694 {
695 /* socket must not be null, and must not be in use/already bound */
696 if (this && m_fd == INVALID_SOCKET)
697 {
698 m_reusable = true;
699
700 return true;
701 }
702
703 return false;
704 }
705
706 bool GSocket::SetBroadcast()
707 {
708 /* socket must not be in use/already bound */
709 if (m_fd == INVALID_SOCKET) {
710 m_broadcast = true;
711 return true;
712 }
713 return false;
714 }
715
716 bool GSocket::DontDoBind()
717 {
718 /* socket must not be in use/already bound */
719 if (m_fd == INVALID_SOCKET) {
720 m_dobind = false;
721 return true;
722 }
723 return false;
724 }
725
726 /* Client specific parts */
727
728 /* GSocket_Connect:
729 * For stream (connection oriented) sockets, GSocket_Connect() tries
730 * to establish a client connection to a server using the peer address
731 * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
732 * connection has been successfully established, or one of the error
733 * codes listed below. Note that for nonblocking sockets, a return
734 * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
735 * request can be completed later; you should use GSocket_Select()
736 * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
737 * corresponding asynchronous events.
738 *
739 * For datagram (non connection oriented) sockets, GSocket_Connect()
740 * just sets the peer address established with GSocket_SetPeer() as
741 * default destination.
742 *
743 * Error codes:
744 * GSOCK_INVSOCK - the socket is in use or not valid.
745 * GSOCK_INVADDR - the peer address has not been established.
746 * GSOCK_TIMEDOUT - timeout, the connection failed.
747 * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
748 * GSOCK_MEMERR - couldn't allocate memory.
749 * GSOCK_IOERR - low-level error.
750 */
751 GSocketError GSocket::Connect(GSocketStream stream)
752 {
753 int err, ret;
754 int arg = 1;
755
756 assert(this);
757
758 /* Enable CONNECTION events (needed for nonblocking connections) */
759 Enable(GSOCK_CONNECTION);
760
761 if (m_fd != INVALID_SOCKET)
762 {
763 m_error = GSOCK_INVSOCK;
764 return GSOCK_INVSOCK;
765 }
766
767 if (!m_peer)
768 {
769 m_error = GSOCK_INVADDR;
770 return GSOCK_INVADDR;
771 }
772
773 /* Streamed or dgram socket? */
774 m_stream = (stream == GSOCK_STREAMED);
775 m_server = false;
776 m_establishing = false;
777
778 /* Create the socket */
779 m_fd = socket(m_peer->m_realfamily,
780 m_stream? SOCK_STREAM : SOCK_DGRAM, 0);
781
782 if (m_fd == INVALID_SOCKET)
783 {
784 m_error = GSOCK_IOERR;
785 return GSOCK_IOERR;
786 }
787
788 /* FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option */
789 #ifdef SO_NOSIGPIPE
790 setsockopt(m_fd, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&arg, sizeof(arg));
791 #endif
792
793 #if defined(__EMX__) || defined(__VISAGECPP__)
794 ioctl(m_fd, FIONBIO, (char*)&arg, sizeof(arg));
795 #else
796 ioctl(m_fd, FIONBIO, &arg);
797 #endif
798
799 // If the reuse flag is set, use the applicable socket reuse flags(s)
800 if (m_reusable)
801 {
802 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(arg));
803 #ifdef SO_REUSEPORT
804 setsockopt(m_fd, SOL_SOCKET, SO_REUSEPORT, (const char*)&arg, sizeof(arg));
805 #endif
806 }
807
808 if (m_initialRecvBufferSize >= 0)
809 setsockopt(m_fd, SOL_SOCKET, SO_RCVBUF, (const char*)&m_initialRecvBufferSize, sizeof(m_initialRecvBufferSize));
810 if (m_initialSendBufferSize >= 0)
811 setsockopt(m_fd, SOL_SOCKET, SO_SNDBUF, (const char*)&m_initialSendBufferSize, sizeof(m_initialSendBufferSize));
812
813 // If a local address has been set, then we need to bind to it before calling connect
814 if (m_local && m_local->m_addr)
815 {
816 bind(m_fd, m_local->m_addr, m_local->m_len);
817 }
818
819 /* Connect it to the peer address, with a timeout (see below) */
820 ret = connect(m_fd, m_peer->m_addr, m_peer->m_len);
821
822 /* We only call Enable_Events if we know we aren't shutting down the socket.
823 * NB: Enable_Events needs to be called whether the socket is blocking or
824 * non-blocking, it just shouldn't be called prior to knowing there is a
825 * connection _if_ blocking sockets are being used.
826 * If connect above returns 0, we are already connected and need to make the
827 * call to Enable_Events now.
828 */
829
830 if (m_use_events && (m_non_blocking || ret == 0))
831 EnableEvents();
832
833 if (ret == -1)
834 {
835 err = errno;
836
837 /* If connect failed with EINPROGRESS and the GSocket object
838 * is in blocking mode, we select() for the specified timeout
839 * checking for writability to see if the connection request
840 * completes.
841 */
842 if ((err == EINPROGRESS) && (!m_non_blocking))
843 {
844 if (Output_Timeout() == GSOCK_TIMEDOUT)
845 {
846 Close();
847 /* m_error is set in _GSocket_Output_Timeout */
848 return GSOCK_TIMEDOUT;
849 }
850 else
851 {
852 int error;
853 SOCKOPTLEN_T len = sizeof(error);
854
855 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*) &error, &len);
856 if (m_use_events)
857 EnableEvents();
858
859 if (!error)
860 return GSOCK_NOERROR;
861 }
862 }
863
864 /* If connect failed with EINPROGRESS and the GSocket object
865 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
866 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
867 * this way if the connection completes, a GSOCK_CONNECTION
868 * event will be generated, if enabled.
869 */
870 if ((err == EINPROGRESS) && (m_non_blocking))
871 {
872 m_establishing = true;
873 m_error = GSOCK_WOULDBLOCK;
874 return GSOCK_WOULDBLOCK;
875 }
876
877 /* If connect failed with an error other than EINPROGRESS,
878 * then the call to GSocket_Connect has failed.
879 */
880 Close();
881 m_error = GSOCK_IOERR;
882
883 return GSOCK_IOERR;
884 }
885
886 return GSOCK_NOERROR;
887 }
888
889 /* Datagram sockets */
890
891 /* GSocket_SetNonOriented:
892 * Sets up this socket as a non-connection oriented (datagram) socket.
893 * Before using this function, the local address must have been set
894 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
895 * on success, or one of the following otherwise.
896 *
897 * Error codes:
898 * GSOCK_INVSOCK - the socket is in use.
899 * GSOCK_INVADDR - the local address has not been set.
900 * GSOCK_IOERR - low-level error.
901 */
902 GSocketError GSocket::SetNonOriented()
903 {
904 int arg = 1;
905
906 assert(this);
907
908 if (m_fd != INVALID_SOCKET)
909 {
910 m_error = GSOCK_INVSOCK;
911 return GSOCK_INVSOCK;
912 }
913
914 if (!m_local)
915 {
916 m_error = GSOCK_INVADDR;
917 return GSOCK_INVADDR;
918 }
919
920 /* Initialize all fields */
921 m_stream = false;
922 m_server = false;
923
924 /* Create the socket */
925 m_fd = socket(m_local->m_realfamily, SOCK_DGRAM, 0);
926
927 if (m_fd == INVALID_SOCKET)
928 {
929 m_error = GSOCK_IOERR;
930 return GSOCK_IOERR;
931 }
932 #if defined(__EMX__) || defined(__VISAGECPP__)
933 ioctl(m_fd, FIONBIO, (char*)&arg, sizeof(arg));
934 #else
935 ioctl(m_fd, FIONBIO, &arg);
936 #endif
937 if (m_use_events)
938 EnableEvents();
939
940 if (m_reusable)
941 {
942 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(arg));
943 #ifdef SO_REUSEPORT
944 setsockopt(m_fd, SOL_SOCKET, SO_REUSEPORT, (const char*)&arg, sizeof(arg));
945 #endif
946 }
947
948 if (m_broadcast)
949 {
950 setsockopt(m_fd, SOL_SOCKET, SO_BROADCAST, (const char*)&arg, sizeof(arg));
951 }
952 if (m_dobind)
953 {
954 /* Bind to the local address,
955 * and retrieve the actual address bound.
956 */
957 if ((bind(m_fd, m_local->m_addr, m_local->m_len) != 0) ||
958 (getsockname(m_fd,
959 m_local->m_addr,
960 (WX_SOCKLEN_T *) &m_local->m_len) != 0))
961 {
962 Close();
963 m_error = GSOCK_IOERR;
964 return GSOCK_IOERR;
965 }
966 }
967 return GSOCK_NOERROR;
968 }
969
970 /* Generic IO */
971
972 /* Like recv(), send(), ... */
973 int GSocket::Read(char *buffer, int size)
974 {
975 int ret;
976
977 assert(this);
978
979 if (m_fd == INVALID_SOCKET || m_server)
980 {
981 m_error = GSOCK_INVSOCK;
982 return -1;
983 }
984
985 /* Disable events during query of socket status */
986 Disable(GSOCK_INPUT);
987
988 /* If the socket is blocking, wait for data (with a timeout) */
989 if (Input_Timeout() == GSOCK_TIMEDOUT) {
990 m_error = GSOCK_TIMEDOUT;
991 /* Don't return here immediately, otherwise socket events would not be
992 * re-enabled! */
993 ret = -1;
994 }
995 else
996 {
997 /* Read the data */
998 if (m_stream)
999 ret = Recv_Stream(buffer, size);
1000 else
1001 ret = Recv_Dgram(buffer, size);
1002
1003 /*
1004 * If recv returned zero for a TCP socket (if m_stream == NULL, it's an UDP
1005 * socket and empty datagrams are possible), then the connection has been
1006 * gracefully closed.
1007 *
1008 * Otherwise, recv has returned an error (-1), in which case we have lost
1009 * the socket only if errno does _not_ indicate that there may be more data
1010 * to read.
1011 */
1012 if ((ret == 0) && m_stream)
1013 {
1014 /* Make sure wxSOCKET_LOST event gets sent and shut down the socket */
1015 if (m_use_events)
1016 {
1017 m_detected = GSOCK_LOST_FLAG;
1018 Detected_Read();
1019 return 0;
1020 }
1021 }
1022 else if (ret == -1)
1023 {
1024 if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
1025 m_error = GSOCK_WOULDBLOCK;
1026 else
1027 m_error = GSOCK_IOERR;
1028 }
1029 }
1030
1031 /* Enable events again now that we are done processing */
1032 Enable(GSOCK_INPUT);
1033
1034 return ret;
1035 }
1036
1037 int GSocket::Write(const char *buffer, int size)
1038 {
1039 int ret;
1040
1041 assert(this);
1042
1043 GSocket_Debug(( "GSocket_Write #1, size %d\n", size ));
1044
1045 if (m_fd == INVALID_SOCKET || m_server)
1046 {
1047 m_error = GSOCK_INVSOCK;
1048 return -1;
1049 }
1050
1051 GSocket_Debug(( "GSocket_Write #2, size %d\n", size ));
1052
1053 /* If the socket is blocking, wait for writability (with a timeout) */
1054 if (Output_Timeout() == GSOCK_TIMEDOUT)
1055 return -1;
1056
1057 GSocket_Debug(( "GSocket_Write #3, size %d\n", size ));
1058
1059 /* Write the data */
1060 if (m_stream)
1061 ret = Send_Stream(buffer, size);
1062 else
1063 ret = Send_Dgram(buffer, size);
1064
1065 GSocket_Debug(( "GSocket_Write #4, size %d\n", size ));
1066
1067 if (ret == -1)
1068 {
1069 if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
1070 {
1071 m_error = GSOCK_WOULDBLOCK;
1072 GSocket_Debug(( "GSocket_Write error WOULDBLOCK\n" ));
1073 }
1074 else
1075 {
1076 m_error = GSOCK_IOERR;
1077 GSocket_Debug(( "GSocket_Write error IOERR\n" ));
1078 }
1079
1080 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
1081 * in MSW). Once the first OUTPUT event is received, users can assume
1082 * that the socket is writable until a read operation fails. Only then
1083 * will further OUTPUT events be posted.
1084 */
1085 Enable(GSOCK_OUTPUT);
1086
1087 return -1;
1088 }
1089
1090 GSocket_Debug(( "GSocket_Write #5, size %d ret %d\n", size, ret ));
1091
1092 return ret;
1093 }
1094
1095 /* Flags */
1096
1097 /* GSocket_SetNonBlocking:
1098 * Sets the socket to non-blocking mode. All IO calls will return
1099 * immediately.
1100 */
1101 void GSocket::SetNonBlocking(bool non_block)
1102 {
1103 assert(this);
1104
1105 GSocket_Debug( ("GSocket_SetNonBlocking: %d\n", (int)non_block) );
1106
1107 m_non_blocking = non_block;
1108 }
1109
1110 /* GSocket_GetError:
1111 * Returns the last error occurred for this socket. Note that successful
1112 * operations do not clear this back to GSOCK_NOERROR, so use it only
1113 * after an error.
1114 */
1115 GSocketError WXDLLIMPEXP_NET GSocket::GetError()
1116 {
1117 assert(this);
1118
1119 return m_error;
1120 }
1121
1122 GSocketError GSocket::GetSockOpt(int level, int optname,
1123 void *optval, int *optlen)
1124 {
1125 if (getsockopt(m_fd, level, optname, (char*)optval, (SOCKOPTLEN_T*)optlen) == 0)
1126 return GSOCK_NOERROR;
1127
1128 return GSOCK_OPTERR;
1129 }
1130
1131 GSocketError GSocket::SetSockOpt(int level, int optname,
1132 const void *optval, int optlen)
1133 {
1134 if (setsockopt(m_fd, level, optname, (const char*)optval, optlen) == 0)
1135 return GSOCK_NOERROR;
1136
1137 return GSOCK_OPTERR;
1138 }
1139
1140 void GSocket::Enable(GSocketEvent event)
1141 {
1142 if (m_use_events)
1143 {
1144 m_detected &= ~(1 << event);
1145 GSocketManager::Get()->Install_Callback(this, event);
1146 }
1147 }
1148
1149 void GSocket::Disable(GSocketEvent event)
1150 {
1151 if (m_use_events)
1152 {
1153 m_detected |= (1 << event);
1154 GSocketManager::Get()->Uninstall_Callback(this, event);
1155 }
1156 }
1157
1158 /* _GSocket_Input_Timeout:
1159 * For blocking sockets, wait until data is available or
1160 * until timeout ellapses.
1161 */
1162 GSocketError GSocket::Input_Timeout()
1163 {
1164 struct timeval tv;
1165 fd_set readfds;
1166 int ret;
1167
1168 /* Linux select() will overwrite the struct on return */
1169 tv.tv_sec = (m_timeout / 1000);
1170 tv.tv_usec = (m_timeout % 1000) * 1000;
1171
1172 if (!m_non_blocking)
1173 {
1174 wxFD_ZERO(&readfds);
1175 wxFD_SET(m_fd, &readfds);
1176 ret = select(m_fd + 1, &readfds, NULL, NULL, &tv);
1177 if (ret == 0)
1178 {
1179 GSocket_Debug(( "GSocket_Input_Timeout, select returned 0\n" ));
1180 m_error = GSOCK_TIMEDOUT;
1181 return GSOCK_TIMEDOUT;
1182 }
1183
1184 if (ret == -1)
1185 {
1186 GSocket_Debug(( "GSocket_Input_Timeout, select returned -1\n" ));
1187 if (errno == EBADF) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1188 if (errno == EINTR) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1189 if (errno == EINVAL) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1190 if (errno == ENOMEM) { GSocket_Debug(( "Not enough memory\n" )); }
1191 m_error = GSOCK_TIMEDOUT;
1192 return GSOCK_TIMEDOUT;
1193 }
1194 }
1195
1196 return GSOCK_NOERROR;
1197 }
1198
1199 /* _GSocket_Output_Timeout:
1200 * For blocking sockets, wait until data can be sent without
1201 * blocking or until timeout ellapses.
1202 */
1203 GSocketError GSocket::Output_Timeout()
1204 {
1205 struct timeval tv;
1206 fd_set writefds;
1207 int ret;
1208
1209 /* Linux select() will overwrite the struct on return */
1210 tv.tv_sec = (m_timeout / 1000);
1211 tv.tv_usec = (m_timeout % 1000) * 1000;
1212
1213 GSocket_Debug( ("m_non_blocking has: %d\n", (int)m_non_blocking) );
1214
1215 if (!m_non_blocking)
1216 {
1217 wxFD_ZERO(&writefds);
1218 wxFD_SET(m_fd, &writefds);
1219 ret = select(m_fd + 1, NULL, &writefds, NULL, &tv);
1220 if (ret == 0)
1221 {
1222 GSocket_Debug(( "GSocket_Output_Timeout, select returned 0\n" ));
1223 m_error = GSOCK_TIMEDOUT;
1224 return GSOCK_TIMEDOUT;
1225 }
1226
1227 if (ret == -1)
1228 {
1229 GSocket_Debug(( "GSocket_Output_Timeout, select returned -1\n" ));
1230 if (errno == EBADF) { GSocket_Debug(( "Invalid file descriptor\n" )); }
1231 if (errno == EINTR) { GSocket_Debug(( "A non blocked signal was caught\n" )); }
1232 if (errno == EINVAL) { GSocket_Debug(( "The highest number descriptor is negative\n" )); }
1233 if (errno == ENOMEM) { GSocket_Debug(( "Not enough memory\n" )); }
1234 m_error = GSOCK_TIMEDOUT;
1235 return GSOCK_TIMEDOUT;
1236 }
1237
1238 if ( ! wxFD_ISSET(m_fd, &writefds) )
1239 {
1240 GSocket_Debug(( "GSocket_Output_Timeout is buggy!\n" ));
1241 }
1242 else
1243 {
1244 GSocket_Debug(( "GSocket_Output_Timeout seems correct\n" ));
1245 }
1246 }
1247 else
1248 {
1249 GSocket_Debug(( "GSocket_Output_Timeout, didn't try select!\n" ));
1250 }
1251
1252 return GSOCK_NOERROR;
1253 }
1254
1255 int GSocket::Recv_Stream(char *buffer, int size)
1256 {
1257 int ret;
1258 do
1259 {
1260 ret = recv(m_fd, buffer, size, GSOCKET_MSG_NOSIGNAL);
1261 }
1262 while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
1263
1264 return ret;
1265 }
1266
1267 int GSocket::Recv_Dgram(char *buffer, int size)
1268 {
1269 wxSockAddr from;
1270 WX_SOCKLEN_T fromlen = sizeof(from);
1271 int ret;
1272 GSocketError err;
1273
1274 fromlen = sizeof(from);
1275
1276 do
1277 {
1278 ret = recvfrom(m_fd, buffer, size, 0, (sockaddr*)&from, (WX_SOCKLEN_T *) &fromlen);
1279 }
1280 while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
1281
1282 if (ret == -1)
1283 return -1;
1284
1285 /* Translate a system address into a GSocket address */
1286 if (!m_peer)
1287 {
1288 m_peer = GAddress_new();
1289 if (!m_peer)
1290 {
1291 m_error = GSOCK_MEMERR;
1292 return -1;
1293 }
1294 }
1295
1296 err = _GAddress_translate_from(m_peer, (sockaddr*)&from, fromlen);
1297 if (err != GSOCK_NOERROR)
1298 {
1299 GAddress_destroy(m_peer);
1300 m_peer = NULL;
1301 m_error = err;
1302 return -1;
1303 }
1304
1305 return ret;
1306 }
1307
1308 int GSocket::Send_Stream(const char *buffer, int size)
1309 {
1310 int ret;
1311
1312 MASK_SIGNAL();
1313
1314 do
1315 {
1316 ret = send(m_fd, (char *)buffer, size, GSOCKET_MSG_NOSIGNAL);
1317 }
1318 while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
1319
1320 UNMASK_SIGNAL();
1321
1322 return ret;
1323 }
1324
1325 int GSocket::Send_Dgram(const char *buffer, int size)
1326 {
1327 struct sockaddr *addr;
1328 int len, ret;
1329 GSocketError err;
1330
1331 if (!m_peer)
1332 {
1333 m_error = GSOCK_INVADDR;
1334 return -1;
1335 }
1336
1337 err = _GAddress_translate_to(m_peer, &addr, &len);
1338 if (err != GSOCK_NOERROR)
1339 {
1340 m_error = err;
1341 return -1;
1342 }
1343
1344 MASK_SIGNAL();
1345
1346 do
1347 {
1348 ret = sendto(m_fd, (char *)buffer, size, 0, addr, len);
1349 }
1350 while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
1351
1352 UNMASK_SIGNAL();
1353
1354 /* Frees memory allocated from _GAddress_translate_to */
1355 free(addr);
1356
1357 return ret;
1358 }
1359
1360 void GSocket::OnStateChange(GSocketEvent event)
1361 {
1362 Disable(event);
1363 NotifyOnStateChange(event);
1364
1365 if ( event == GSOCK_LOST )
1366 Shutdown();
1367 }
1368
1369 void GSocket::Detected_Read()
1370 {
1371 char c;
1372
1373 /* Safeguard against straggling call to Detected_Read */
1374 if (m_fd == INVALID_SOCKET)
1375 {
1376 return;
1377 }
1378
1379 /* If we have already detected a LOST event, then don't try
1380 * to do any further processing.
1381 */
1382 if ((m_detected & GSOCK_LOST_FLAG) != 0)
1383 {
1384 m_establishing = false;
1385
1386 OnStateChange(GSOCK_LOST);
1387 return;
1388 }
1389
1390 int num = recv(m_fd, &c, 1, MSG_PEEK | GSOCKET_MSG_NOSIGNAL);
1391
1392 if (num > 0)
1393 {
1394 OnStateChange(GSOCK_INPUT);
1395 }
1396 else
1397 {
1398 if (m_server && m_stream)
1399 {
1400 OnStateChange(GSOCK_CONNECTION);
1401 }
1402 else if (num == 0)
1403 {
1404 if (m_stream)
1405 {
1406 /* graceful shutdown */
1407 OnStateChange(GSOCK_LOST);
1408 }
1409 else
1410 {
1411 /* Empty datagram received */
1412 OnStateChange(GSOCK_INPUT);
1413 }
1414 }
1415 else
1416 {
1417 /* Do not throw a lost event in cases where the socket isn't really lost */
1418 if ((errno == EWOULDBLOCK) || (errno == EAGAIN) || (errno == EINTR))
1419 {
1420 OnStateChange(GSOCK_INPUT);
1421 }
1422 else
1423 {
1424 OnStateChange(GSOCK_LOST);
1425 }
1426 }
1427 }
1428 }
1429
1430 void GSocket::Detected_Write()
1431 {
1432 /* If we have already detected a LOST event, then don't try
1433 * to do any further processing.
1434 */
1435 if ((m_detected & GSOCK_LOST_FLAG) != 0)
1436 {
1437 m_establishing = false;
1438
1439 OnStateChange(GSOCK_LOST);
1440 return;
1441 }
1442
1443 if (m_establishing && !m_server)
1444 {
1445 int error;
1446 SOCKOPTLEN_T len = sizeof(error);
1447
1448 m_establishing = false;
1449
1450 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
1451
1452 if (error)
1453 {
1454 OnStateChange(GSOCK_LOST);
1455 }
1456 else
1457 {
1458 OnStateChange(GSOCK_CONNECTION);
1459 /* We have to fire this event by hand because CONNECTION (for clients)
1460 * and OUTPUT are internally the same and we just disabled CONNECTION
1461 * events with the above macro.
1462 */
1463 OnStateChange(GSOCK_OUTPUT);
1464 }
1465 }
1466 else
1467 {
1468 OnStateChange(GSOCK_OUTPUT);
1469 }
1470 }
1471
1472 /*
1473 * -------------------------------------------------------------------------
1474 * GAddress
1475 * -------------------------------------------------------------------------
1476 */
1477
1478 /* CHECK_ADDRESS verifies that the current address family is either
1479 * GSOCK_NOFAMILY or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it
1480 * initalizes it to be a GSOCK_*family*. In other cases, it returns
1481 * an appropiate error code.
1482 *
1483 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
1484 */
1485 #define CHECK_ADDRESS(address, family) \
1486 { \
1487 if (address->m_family == GSOCK_NOFAMILY) \
1488 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1489 return address->m_error; \
1490 if (address->m_family != GSOCK_##family) \
1491 { \
1492 address->m_error = GSOCK_INVADDR; \
1493 return GSOCK_INVADDR; \
1494 } \
1495 }
1496
1497 #define CHECK_ADDRESS_RETVAL(address, family, retval) \
1498 { \
1499 if (address->m_family == GSOCK_NOFAMILY) \
1500 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1501 return retval; \
1502 if (address->m_family != GSOCK_##family) \
1503 { \
1504 address->m_error = GSOCK_INVADDR; \
1505 return retval; \
1506 } \
1507 }
1508
1509
1510 GAddress *GAddress_new(void)
1511 {
1512 GAddress *address;
1513
1514 if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1515 return NULL;
1516
1517 address->m_family = GSOCK_NOFAMILY;
1518 address->m_addr = NULL;
1519 address->m_len = 0;
1520
1521 return address;
1522 }
1523
1524 GAddress *GAddress_copy(GAddress *address)
1525 {
1526 GAddress *addr2;
1527
1528 assert(address != NULL);
1529
1530 if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
1531 return NULL;
1532
1533 memcpy(addr2, address, sizeof(GAddress));
1534
1535 if (address->m_addr && address->m_len > 0)
1536 {
1537 addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
1538 if (addr2->m_addr == NULL)
1539 {
1540 free(addr2);
1541 return NULL;
1542 }
1543 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
1544 }
1545
1546 return addr2;
1547 }
1548
1549 void GAddress_destroy(GAddress *address)
1550 {
1551 assert(address != NULL);
1552
1553 if (address->m_addr)
1554 free(address->m_addr);
1555
1556 free(address);
1557 }
1558
1559 void GAddress_SetFamily(GAddress *address, GAddressType type)
1560 {
1561 assert(address != NULL);
1562
1563 address->m_family = type;
1564 }
1565
1566 GAddressType GAddress_GetFamily(GAddress *address)
1567 {
1568 assert(address != NULL);
1569
1570 return address->m_family;
1571 }
1572
1573 GSocketError _GAddress_translate_from(GAddress *address,
1574 struct sockaddr *addr, int len)
1575 {
1576 address->m_realfamily = addr->sa_family;
1577 switch (addr->sa_family)
1578 {
1579 case AF_INET:
1580 address->m_family = GSOCK_INET;
1581 break;
1582 case AF_UNIX:
1583 address->m_family = GSOCK_UNIX;
1584 break;
1585 #if wxUSE_IPV6
1586 case AF_INET6:
1587 address->m_family = GSOCK_INET6;
1588 break;
1589 #endif // wxUSE_IPV6
1590 default:
1591 {
1592 address->m_error = GSOCK_INVOP;
1593 return GSOCK_INVOP;
1594 }
1595 }
1596
1597 if (address->m_addr)
1598 free(address->m_addr);
1599
1600 address->m_len = len;
1601 address->m_addr = (struct sockaddr *)malloc(len);
1602
1603 if (address->m_addr == NULL)
1604 {
1605 address->m_error = GSOCK_MEMERR;
1606 return GSOCK_MEMERR;
1607 }
1608
1609 memcpy(address->m_addr, addr, len);
1610
1611 return GSOCK_NOERROR;
1612 }
1613
1614 GSocketError _GAddress_translate_to(GAddress *address,
1615 struct sockaddr **addr, int *len)
1616 {
1617 if (!address->m_addr)
1618 {
1619 address->m_error = GSOCK_INVADDR;
1620 return GSOCK_INVADDR;
1621 }
1622
1623 *len = address->m_len;
1624 *addr = (struct sockaddr *)malloc(address->m_len);
1625 if (*addr == NULL)
1626 {
1627 address->m_error = GSOCK_MEMERR;
1628 return GSOCK_MEMERR;
1629 }
1630
1631 memcpy(*addr, address->m_addr, address->m_len);
1632 return GSOCK_NOERROR;
1633 }
1634
1635 /*
1636 * -------------------------------------------------------------------------
1637 * Internet address family
1638 * -------------------------------------------------------------------------
1639 */
1640
1641 GSocketError _GAddress_Init_INET(GAddress *address)
1642 {
1643 address->m_len = sizeof(struct sockaddr_in);
1644 address->m_addr = (struct sockaddr *) malloc(address->m_len);
1645 if (address->m_addr == NULL)
1646 {
1647 address->m_error = GSOCK_MEMERR;
1648 return GSOCK_MEMERR;
1649 }
1650
1651 address->m_family = GSOCK_INET;
1652 address->m_realfamily = PF_INET;
1653 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
1654 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
1655
1656 return GSOCK_NOERROR;
1657 }
1658
1659 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
1660 {
1661 struct hostent *he;
1662 struct in_addr *addr;
1663
1664 assert(address != NULL);
1665
1666 CHECK_ADDRESS(address, INET);
1667
1668 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1669
1670 /* If it is a numeric host name, convert it now */
1671 #if defined(HAVE_INET_ATON)
1672 if (inet_aton(hostname, addr) == 0)
1673 {
1674 #elif defined(HAVE_INET_ADDR)
1675 if ( (addr->s_addr = inet_addr(hostname)) == (unsigned)-1 )
1676 {
1677 #else
1678 /* Use gethostbyname by default */
1679 #ifndef __WXMAC__
1680 int val = 1; /* VA doesn't like constants in conditional expressions */
1681 if (val)
1682 #endif
1683 {
1684 #endif
1685 struct in_addr *array_addr;
1686
1687 /* It is a real name, we solve it */
1688 struct hostent h;
1689 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
1690 struct hostent_data buffer;
1691 #else
1692 char buffer[1024];
1693 #endif
1694 int err;
1695 he = wxGethostbyname_r(hostname, &h, (void*)&buffer, sizeof(buffer), &err);
1696 if (he == NULL)
1697 {
1698 /* Reset to invalid address */
1699 addr->s_addr = INADDR_NONE;
1700 address->m_error = GSOCK_NOHOST;
1701 return GSOCK_NOHOST;
1702 }
1703
1704 array_addr = (struct in_addr *) *(he->h_addr_list);
1705 addr->s_addr = array_addr[0].s_addr;
1706 }
1707
1708 return GSOCK_NOERROR;
1709 }
1710
1711
1712 GSocketError GAddress_INET_SetBroadcastAddress(GAddress *address)
1713 {
1714 return GAddress_INET_SetHostAddress(address, INADDR_BROADCAST);
1715 }
1716
1717 GSocketError GAddress_INET_SetAnyAddress(GAddress *address)
1718 {
1719 return GAddress_INET_SetHostAddress(address, INADDR_ANY);
1720 }
1721
1722 GSocketError GAddress_INET_SetHostAddress(GAddress *address,
1723 unsigned long hostaddr)
1724 {
1725 struct in_addr *addr;
1726
1727 assert(address != NULL);
1728
1729 CHECK_ADDRESS(address, INET);
1730
1731 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
1732 addr->s_addr = htonl(hostaddr);
1733
1734 return GSOCK_NOERROR;
1735 }
1736
1737 GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
1738 const char *protocol)
1739 {
1740 struct servent *se;
1741 struct sockaddr_in *addr;
1742
1743 assert(address != NULL);
1744 CHECK_ADDRESS(address, INET);
1745
1746 if (!port)
1747 {
1748 address->m_error = GSOCK_INVPORT;
1749 return GSOCK_INVPORT;
1750 }
1751
1752 #if defined(HAVE_FUNC_GETSERVBYNAME_R_4)
1753 struct servent_data buffer;
1754 #else
1755 char buffer[1024];
1756 #endif
1757 struct servent serv;
1758 se = wxGetservbyname_r(port, protocol, &serv,
1759 (void*)&buffer, sizeof(buffer));
1760 if (!se)
1761 {
1762 /* the cast to int suppresses compiler warnings about subscript having the
1763 type char */
1764 if (isdigit((int)port[0]))
1765 {
1766 int port_int;
1767
1768 port_int = atoi(port);
1769 addr = (struct sockaddr_in *)address->m_addr;
1770 addr->sin_port = htons(port_int);
1771 return GSOCK_NOERROR;
1772 }
1773
1774 address->m_error = GSOCK_INVPORT;
1775 return GSOCK_INVPORT;
1776 }
1777
1778 addr = (struct sockaddr_in *)address->m_addr;
1779 addr->sin_port = se->s_port;
1780
1781 return GSOCK_NOERROR;
1782 }
1783
1784 GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
1785 {
1786 struct sockaddr_in *addr;
1787
1788 assert(address != NULL);
1789 CHECK_ADDRESS(address, INET);
1790
1791 addr = (struct sockaddr_in *)address->m_addr;
1792 addr->sin_port = htons(port);
1793
1794 return GSOCK_NOERROR;
1795 }
1796
1797 GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1798 {
1799 struct hostent *he;
1800 char *addr_buf;
1801 struct sockaddr_in *addr;
1802
1803 assert(address != NULL);
1804 CHECK_ADDRESS(address, INET);
1805
1806 addr = (struct sockaddr_in *)address->m_addr;
1807 addr_buf = (char *)&(addr->sin_addr);
1808
1809 struct hostent temphost;
1810 #if defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
1811 struct hostent_data buffer;
1812 #else
1813 char buffer[1024];
1814 #endif
1815 int err;
1816 he = wxGethostbyaddr_r(addr_buf, sizeof(addr->sin_addr), AF_INET, &temphost,
1817 (void*)&buffer, sizeof(buffer), &err);
1818 if (he == NULL)
1819 {
1820 address->m_error = GSOCK_NOHOST;
1821 return GSOCK_NOHOST;
1822 }
1823
1824 strncpy(hostname, he->h_name, sbuf);
1825
1826 return GSOCK_NOERROR;
1827 }
1828
1829 unsigned long GAddress_INET_GetHostAddress(GAddress *address)
1830 {
1831 struct sockaddr_in *addr;
1832
1833 assert(address != NULL);
1834 CHECK_ADDRESS_RETVAL(address, INET, 0);
1835
1836 addr = (struct sockaddr_in *)address->m_addr;
1837
1838 return ntohl(addr->sin_addr.s_addr);
1839 }
1840
1841 unsigned short GAddress_INET_GetPort(GAddress *address)
1842 {
1843 struct sockaddr_in *addr;
1844
1845 assert(address != NULL);
1846 CHECK_ADDRESS_RETVAL(address, INET, 0);
1847
1848 addr = (struct sockaddr_in *)address->m_addr;
1849 return ntohs(addr->sin_port);
1850 }
1851
1852 #if wxUSE_IPV6
1853 /*
1854 * -------------------------------------------------------------------------
1855 * Internet IPv6 address family
1856 * -------------------------------------------------------------------------
1857 */
1858
1859 GSocketError _GAddress_Init_INET6(GAddress *address)
1860 {
1861 struct in6_addr any_address = IN6ADDR_ANY_INIT;
1862 address->m_len = sizeof(struct sockaddr_in6);
1863 address->m_addr = (struct sockaddr *) malloc(address->m_len);
1864 if (address->m_addr == NULL)
1865 {
1866 address->m_error = GSOCK_MEMERR;
1867 return GSOCK_MEMERR;
1868 }
1869 memset(address->m_addr,0,address->m_len);
1870
1871 address->m_family = GSOCK_INET6;
1872 address->m_realfamily = AF_INET6;
1873 ((struct sockaddr_in6 *)address->m_addr)->sin6_family = AF_INET6;
1874 ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = any_address;
1875
1876 return GSOCK_NOERROR;
1877 }
1878
1879 GSocketError GAddress_INET6_SetHostName(GAddress *address, const char *hostname)
1880 {
1881 assert(address != NULL);
1882 CHECK_ADDRESS(address, INET6);
1883
1884 addrinfo hints;
1885 memset( & hints, 0, sizeof( hints ) );
1886 hints.ai_family = AF_INET6;
1887 addrinfo * info = 0;
1888 if ( getaddrinfo( hostname, "0", & hints, & info ) || ! info )
1889 {
1890 address->m_error = GSOCK_NOHOST;
1891 return GSOCK_NOHOST;
1892 }
1893
1894 memcpy( address->m_addr, info->ai_addr, info->ai_addrlen );
1895 freeaddrinfo( info );
1896 return GSOCK_NOERROR;
1897 }
1898
1899 GSocketError GAddress_INET6_SetAnyAddress(GAddress *address)
1900 {
1901 assert(address != NULL);
1902
1903 CHECK_ADDRESS(address, INET6);
1904
1905 struct in6_addr addr;
1906 memset( & addr, 0, sizeof( addr ) );
1907 return GAddress_INET6_SetHostAddress(address, addr);
1908 }
1909 GSocketError GAddress_INET6_SetHostAddress(GAddress *address,
1910 struct in6_addr hostaddr)
1911 {
1912 assert(address != NULL);
1913
1914 CHECK_ADDRESS(address, INET6);
1915
1916 ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = hostaddr;
1917
1918 return GSOCK_NOERROR;
1919 }
1920
1921 GSocketError GAddress_INET6_SetPortName(GAddress *address, const char *port,
1922 const char *protocol)
1923 {
1924 struct servent *se;
1925 struct sockaddr_in6 *addr;
1926
1927 assert(address != NULL);
1928 CHECK_ADDRESS(address, INET6);
1929
1930 if (!port)
1931 {
1932 address->m_error = GSOCK_INVPORT;
1933 return GSOCK_INVPORT;
1934 }
1935
1936 se = getservbyname(port, protocol);
1937 if (!se)
1938 {
1939 if (isdigit(port[0]))
1940 {
1941 int port_int;
1942
1943 port_int = atoi(port);
1944 addr = (struct sockaddr_in6 *)address->m_addr;
1945 addr->sin6_port = htons((u_short) port_int);
1946 return GSOCK_NOERROR;
1947 }
1948
1949 address->m_error = GSOCK_INVPORT;
1950 return GSOCK_INVPORT;
1951 }
1952
1953 addr = (struct sockaddr_in6 *)address->m_addr;
1954 addr->sin6_port = se->s_port;
1955
1956 return GSOCK_NOERROR;
1957 }
1958
1959 GSocketError GAddress_INET6_SetPort(GAddress *address, unsigned short port)
1960 {
1961 struct sockaddr_in6 *addr;
1962
1963 assert(address != NULL);
1964 CHECK_ADDRESS(address, INET6);
1965
1966 addr = (struct sockaddr_in6 *)address->m_addr;
1967 addr->sin6_port = htons(port);
1968
1969 return GSOCK_NOERROR;
1970 }
1971
1972 GSocketError GAddress_INET6_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1973 {
1974 struct hostent *he;
1975 char *addr_buf;
1976 struct sockaddr_in6 *addr;
1977
1978 assert(address != NULL);
1979 CHECK_ADDRESS(address, INET6);
1980
1981 addr = (struct sockaddr_in6 *)address->m_addr;
1982 addr_buf = (char *)&(addr->sin6_addr);
1983
1984 he = gethostbyaddr(addr_buf, sizeof(addr->sin6_addr), AF_INET6);
1985 if (he == NULL)
1986 {
1987 address->m_error = GSOCK_NOHOST;
1988 return GSOCK_NOHOST;
1989 }
1990
1991 strncpy(hostname, he->h_name, sbuf);
1992
1993 return GSOCK_NOERROR;
1994 }
1995
1996 GSocketError GAddress_INET6_GetHostAddress(GAddress *address,struct in6_addr *hostaddr)
1997 {
1998 assert(address != NULL);
1999 assert(hostaddr != NULL);
2000 CHECK_ADDRESS_RETVAL(address, INET6, GSOCK_INVADDR);
2001 *hostaddr = ( (struct sockaddr_in6 *)address->m_addr )->sin6_addr;
2002 return GSOCK_NOERROR;
2003 }
2004
2005 unsigned short GAddress_INET6_GetPort(GAddress *address)
2006 {
2007 assert(address != NULL);
2008 CHECK_ADDRESS_RETVAL(address, INET6, 0);
2009
2010 return ntohs( ((struct sockaddr_in6 *)address->m_addr)->sin6_port );
2011 }
2012
2013 #endif // wxUSE_IPV6
2014
2015 /*
2016 * -------------------------------------------------------------------------
2017 * Unix address family
2018 * -------------------------------------------------------------------------
2019 */
2020
2021 #ifndef __VISAGECPP__
2022 GSocketError _GAddress_Init_UNIX(GAddress *address)
2023 {
2024 address->m_len = sizeof(struct sockaddr_un);
2025 address->m_addr = (struct sockaddr *)malloc(address->m_len);
2026 if (address->m_addr == NULL)
2027 {
2028 address->m_error = GSOCK_MEMERR;
2029 return GSOCK_MEMERR;
2030 }
2031
2032 address->m_family = GSOCK_UNIX;
2033 address->m_realfamily = PF_UNIX;
2034 ((struct sockaddr_un *)address->m_addr)->sun_family = AF_UNIX;
2035 ((struct sockaddr_un *)address->m_addr)->sun_path[0] = 0;
2036
2037 return GSOCK_NOERROR;
2038 }
2039
2040 #define UNIX_SOCK_PATHLEN (sizeof(addr->sun_path)/sizeof(addr->sun_path[0]))
2041
2042 GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
2043 {
2044 struct sockaddr_un *addr;
2045
2046 assert(address != NULL);
2047
2048 CHECK_ADDRESS(address, UNIX);
2049
2050 addr = ((struct sockaddr_un *)address->m_addr);
2051 strncpy(addr->sun_path, path, UNIX_SOCK_PATHLEN);
2052 addr->sun_path[UNIX_SOCK_PATHLEN - 1] = '\0';
2053
2054 return GSOCK_NOERROR;
2055 }
2056
2057 GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
2058 {
2059 struct sockaddr_un *addr;
2060
2061 assert(address != NULL);
2062 CHECK_ADDRESS(address, UNIX);
2063
2064 addr = (struct sockaddr_un *)address->m_addr;
2065
2066 strncpy(path, addr->sun_path, sbuf);
2067
2068 return GSOCK_NOERROR;
2069 }
2070 #endif /* !defined(__VISAGECPP__) */
2071 #endif /* wxUSE_SOCKETS */