DEFINITIONS
This source file includes following functions.
- ruby_getaddrinfo
- sock_finalize
- init_sock
- bsock_s_for_fd
- bsock_shutdown
- bsock_close_read
- bsock_close_write
- bsock_setsockopt
- bsock_getsockopt
- bsock_getsockname
- bsock_getpeername
- bsock_send
- s_recvfrom
- bsock_recv
- bsock_do_not_rev_lookup
- bsock_do_not_rev_lookup_set
- mkipaddr0
- mkipaddr
- mkinetaddr
- str_isnumber
- sock_addrinfo
- setipaddr
- ipaddr
- ruby_socket
- thread_read_select
- thread_write_select
- ruby_connect
- load_addr_info
- inetsock_cleanup
- init_inetsock_internal
- init_inetsock
- tcp_init
- socks_init
- socks_s_close
- sock_hostbyname
- tcp_s_gethostbyname
- tcp_svr_init
- s_accept
- tcp_accept
- tcp_sysaccept
- unixsock_connect_internal
- init_unixsock
- ip_addr
- ip_peeraddr
- ip_recvfrom
- ip_s_getaddress
- udp_init
- udp_connect_internal
- udp_connect
- udp_bind
- udp_send
- unix_init
- unix_path
- unix_svr_s_open
- unix_svr_init
- unix_recvfrom
- unix_send_io
- unix_recv_io
- unix_accept
- unix_sysaccept
- unixaddr
- unix_addr
- unix_peeraddr
- setup_domain_and_type
- sock_init
- sock_s_socketpair
- unix_s_socketpair
- sock_connect
- sock_bind
- sock_listen
- sock_recvfrom
- sock_accept
- sock_sysaccept
- sock_gethostname
- sock_gethostname
- sock_gethostname
- sock_mkhostent
- mkaddrinfo
- sock_s_gethostbyname
- sock_s_gethostbyaddr
- sock_s_getservbyaname
- sock_s_getaddrinfo
- sock_s_getnameinfo
- sock_s_pack_sockaddr_in
- sock_s_unpack_sockaddr_in
- sock_s_pack_sockaddr_un
- sock_s_unpack_sockaddr_un
- sock_define_const
- Init_socket
1
2
3
4
5
6
7
8
9
10
11
12
13 #include "ruby.h"
14 #include "rubyio.h"
15 #include "rubysig.h"
16 #include <stdio.h>
17 #include <sys/types.h>
18
19 #ifdef HAVE_UNISTD_H
20 #include <unistd.h>
21 #endif
22
23 #ifdef HAVE_SYS_UIO_H
24 #include <sys/uio.h>
25 #endif
26
27 #ifndef NT
28 #if defined(__BEOS__)
29 # include <net/socket.h>
30 #else
31 # include <sys/socket.h>
32 #endif
33 #include <netinet/in.h>
34 #ifdef HAVE_NETINET_TCP_H
35 # include <netinet/tcp.h>
36 #endif
37 #ifdef HAVE_NETINET_UDP_H
38 # include <netinet/udp.h>
39 #endif
40 #include <netdb.h>
41 #endif
42 #include <errno.h>
43 #ifdef HAVE_SYS_UN_H
44 #include <sys/un.h>
45 #endif
46
47 #if defined(HAVE_FCNTL)
48 #ifdef HAVE_SYS_SELECT_H
49 #include <sys/select.h>
50 #endif
51 #include <sys/types.h>
52 #include <sys/time.h>
53 #include <fcntl.h>
54 #endif
55 #ifndef EWOULDBLOCK
56 #define EWOULDBLOCK EAGAIN
57 #endif
58 #ifndef HAVE_GETADDRINFO
59 # include "addrinfo.h"
60 #endif
61 #include "sockport.h"
62
63 static int do_not_reverse_lookup = 0;
64
65 VALUE rb_cBasicSocket;
66 VALUE rb_cIPSocket;
67 VALUE rb_cTCPSocket;
68 VALUE rb_cTCPServer;
69 VALUE rb_cUDPSocket;
70 #ifdef AF_UNIX
71 VALUE rb_cUNIXSocket;
72 VALUE rb_cUNIXServer;
73 #endif
74 VALUE rb_cSocket;
75
76 static VALUE rb_eSocket;
77
78 #ifdef SOCKS
79 VALUE rb_cSOCKSSocket;
80 #ifdef SOCKS5
81 #include <socks.h>
82 #else
83 void SOCKSinit();
84 int Rconnect();
85 #endif
86 #endif
87
88 #define INET_CLIENT 0
89 #define INET_SERVER 1
90 #define INET_SOCKS 2
91
92 #ifndef HAVE_SOCKADDR_STORAGE
93
94
95
96 #define _SS_MAXSIZE 128
97 #define _SS_ALIGNSIZE (sizeof(double))
98 #define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(unsigned char) * 2)
99 #define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(unsigned char) * 2 - \
100 _SS_PAD1SIZE - _SS_ALIGNSIZE)
101
102 struct sockaddr_storage {
103 #ifdef HAVE_SA_LEN
104 unsigned char ss_len;
105 unsigned char ss_family;
106 #else
107 unsigned short ss_family;
108 #endif
109 char __ss_pad1[_SS_PAD1SIZE];
110 double __ss_align;
111 char __ss_pad2[_SS_PAD2SIZE];
112 };
113 #endif
114
115 #if defined(INET6) && (defined(LOOKUP_ORDER_HACK_INET) || defined(LOOKUP_ORDER_HACK_INET6))
116 #define LOOKUP_ORDERS 3
117 static int lookup_order_table[LOOKUP_ORDERS] = {
118 #if defined(LOOKUP_ORDER_HACK_INET)
119 PF_INET, PF_INET6, PF_UNSPEC,
120 #elif defined(LOOKUP_ORDER_HACK_INET6)
121 PF_INET6, PF_INET, PF_UNSPEC,
122 #else
123
124 #endif
125 };
126
127 static int
128 ruby_getaddrinfo(nodename, servname, hints, res)
129 char *nodename;
130 char *servname;
131 struct addrinfo *hints;
132 struct addrinfo **res;
133 {
134 struct addrinfo tmp_hints;
135 int i, af, error;
136
137 if (hints->ai_family != PF_UNSPEC) {
138 return getaddrinfo(nodename, servname, hints, res);
139 }
140
141 for (i = 0; i < LOOKUP_ORDERS; i++) {
142 af = lookup_order_table[i];
143 MEMCPY(&tmp_hints, hints, struct addrinfo, 1);
144 tmp_hints.ai_family = af;
145 error = getaddrinfo(nodename, servname, &tmp_hints, res);
146 if (error) {
147 if (tmp_hints.ai_family == PF_UNSPEC) {
148 break;
149 }
150 }
151 else {
152 break;
153 }
154 }
155
156 return error;
157 }
158 #define getaddrinfo(node,serv,hints,res) ruby_getaddrinfo((node),(serv),(hints),(res))
159 #endif
160
161 #ifdef HAVE_CLOSESOCKET
162 #undef close
163 #define close closesocket
164 #endif
165
166 #ifdef NT
167 static void sock_finalize _((OpenFile *fptr));
168
169 static void
170 sock_finalize(fptr)
171 OpenFile *fptr;
172 {
173 SOCKET s;
174
175 if (!fptr->f) return;
176 s = get_osfhandle(fileno(fptr->f));
177 rb_w32_fdclose(fptr->f);
178 if (fptr->f2) rb_w32_fdclose(fptr->f2);
179 closesocket(s);
180 }
181 #endif
182
183 static VALUE
184 init_sock(sock, fd)
185 VALUE sock;
186 int fd;
187 {
188 OpenFile *fp;
189
190 MakeOpenFile(sock, fp);
191 fp->f = rb_fdopen(fd, "r");
192 #ifdef NT
193 fp->finalize = sock_finalize;
194 #endif
195 fp->f2 = rb_fdopen(fd, "w");
196 fp->mode = FMODE_READWRITE;
197 rb_io_synchronized(fp);
198
199 return sock;
200 }
201
202 static VALUE
203 bsock_s_for_fd(klass, fd)
204 VALUE klass, fd;
205 {
206 OpenFile *fptr;
207 VALUE sock = init_sock(rb_obj_alloc(klass), NUM2INT(fd));
208
209 GetOpenFile(sock, fptr);
210
211 return sock;
212 }
213
214 static VALUE
215 bsock_shutdown(argc, argv, sock)
216 int argc;
217 VALUE *argv;
218 VALUE sock;
219 {
220 VALUE howto;
221 int how;
222 OpenFile *fptr;
223
224 if (rb_safe_level() >= 4 && !OBJ_TAINTED(sock)) {
225 rb_raise(rb_eSecurityError, "Insecure: can't shutdown socket");
226 }
227 rb_scan_args(argc, argv, "01", &howto);
228 if (howto == Qnil)
229 how = 2;
230 else {
231 how = NUM2INT(howto);
232 if (how < 0 || 2 < how) {
233 rb_raise(rb_eArgError, "`how' should be either 0, 1, 2");
234 }
235 }
236 GetOpenFile(sock, fptr);
237 if (shutdown(fileno(fptr->f), how) == -1)
238 rb_sys_fail(0);
239
240 return INT2FIX(0);
241 }
242
243 static VALUE
244 bsock_close_read(sock)
245 VALUE sock;
246 {
247 OpenFile *fptr;
248
249 if (rb_safe_level() >= 4 && !OBJ_TAINTED(sock)) {
250 rb_raise(rb_eSecurityError, "Insecure: can't close socket");
251 }
252 GetOpenFile(sock, fptr);
253 shutdown(fileno(fptr->f), 0);
254 if (!(fptr->mode & FMODE_WRITABLE)) {
255 return rb_io_close(sock);
256 }
257 fptr->mode &= ~FMODE_READABLE;
258
259 return Qnil;
260 }
261
262 static VALUE
263 bsock_close_write(sock)
264 VALUE sock;
265 {
266 OpenFile *fptr;
267
268 if (rb_safe_level() >= 4 && !OBJ_TAINTED(sock)) {
269 rb_raise(rb_eSecurityError, "Insecure: can't close socket");
270 }
271 GetOpenFile(sock, fptr);
272 if (!(fptr->mode & FMODE_READABLE)) {
273 return rb_io_close(sock);
274 }
275 shutdown(fileno(fptr->f2), 1);
276 fptr->mode &= ~FMODE_WRITABLE;
277
278 return Qnil;
279 }
280
281 static VALUE
282 bsock_setsockopt(sock, lev, optname, val)
283 VALUE sock, lev, optname, val;
284 {
285 int level, option;
286 OpenFile *fptr;
287 int i;
288 char *v;
289 int vlen;
290
291 rb_secure(2);
292 level = NUM2INT(lev);
293 option = NUM2INT(optname);
294 switch (TYPE(val)) {
295 case T_FIXNUM:
296 i = FIX2INT(val);
297 goto numval;
298 case T_FALSE:
299 i = 0;
300 goto numval;
301 case T_TRUE:
302 i = 1;
303 numval:
304 v = (char*)&i; vlen = sizeof(i);
305 break;
306 default:
307 StringValue(val);
308 v = RSTRING(val)->ptr;
309 vlen = RSTRING(val)->len;
310 break;
311 }
312
313 GetOpenFile(sock, fptr);
314 if (setsockopt(fileno(fptr->f), level, option, v, vlen) < 0)
315 rb_sys_fail(fptr->path);
316
317 return INT2FIX(0);
318 }
319
320 static VALUE
321 bsock_getsockopt(sock, lev, optname)
322 VALUE sock, lev, optname;
323 {
324 #if !defined(__BEOS__)
325 int level, option;
326 socklen_t len;
327 char *buf;
328 OpenFile *fptr;
329
330 level = NUM2INT(lev);
331 option = NUM2INT(optname);
332 len = 256;
333 buf = ALLOCA_N(char,len);
334
335 GetOpenFile(sock, fptr);
336 if (getsockopt(fileno(fptr->f), level, option, buf, &len) < 0)
337 rb_sys_fail(fptr->path);
338
339 return rb_str_new(buf, len);
340 #else
341 rb_notimplement();
342 #endif
343 }
344
345 static VALUE
346 bsock_getsockname(sock)
347 VALUE sock;
348 {
349 char buf[1024];
350 socklen_t len = sizeof buf;
351 OpenFile *fptr;
352
353 GetOpenFile(sock, fptr);
354 if (getsockname(fileno(fptr->f), (struct sockaddr*)buf, &len) < 0)
355 rb_sys_fail("getsockname(2)");
356 return rb_str_new(buf, len);
357 }
358
359 static VALUE
360 bsock_getpeername(sock)
361 VALUE sock;
362 {
363 char buf[1024];
364 socklen_t len = sizeof buf;
365 OpenFile *fptr;
366
367 GetOpenFile(sock, fptr);
368 if (getpeername(fileno(fptr->f), (struct sockaddr*)buf, &len) < 0)
369 rb_sys_fail("getpeername(2)");
370 return rb_str_new(buf, len);
371 }
372
373 static VALUE
374 bsock_send(argc, argv, sock)
375 int argc;
376 VALUE *argv;
377 VALUE sock;
378 {
379 VALUE mesg, to;
380 VALUE flags;
381 OpenFile *fptr;
382 FILE *f;
383 int fd, n;
384
385 rb_secure(4);
386 rb_scan_args(argc, argv, "21", &mesg, &flags, &to);
387
388 GetOpenFile(sock, fptr);
389 f = GetWriteFile(fptr);
390 fd = fileno(f);
391 retry:
392 rb_thread_fd_writable(fd);
393 StringValue(mesg);
394 if (!NIL_P(to)) {
395 StringValue(to);
396 n = sendto(fd, RSTRING(mesg)->ptr, RSTRING(mesg)->len, NUM2INT(flags),
397 (struct sockaddr*)RSTRING(to)->ptr, RSTRING(to)->len);
398 }
399 else {
400 n = send(fd, RSTRING(mesg)->ptr, RSTRING(mesg)->len, NUM2INT(flags));
401 }
402 if (n < 0) {
403 switch (errno) {
404 case EINTR:
405 rb_thread_schedule();
406 goto retry;
407 }
408 rb_sys_fail("send(2)");
409 }
410 return INT2FIX(n);
411 }
412
413 static VALUE ipaddr _((struct sockaddr*));
414 #ifdef HAVE_SYS_UN_H
415 static VALUE unixaddr _((struct sockaddr_un*));
416 #endif
417
418 enum sock_recv_type {
419 RECV_RECV,
420 RECV_IP,
421 RECV_UNIX,
422 RECV_SOCKET
423 };
424
425 static VALUE
426 s_recvfrom(sock, argc, argv, from)
427 VALUE sock;
428 int argc;
429 VALUE *argv;
430 enum sock_recv_type from;
431 {
432 OpenFile *fptr;
433 VALUE str;
434 char buf[1024];
435 socklen_t alen = sizeof buf;
436 VALUE len, flg;
437 long slen;
438 int fd, flags;
439
440 rb_scan_args(argc, argv, "11", &len, &flg);
441
442 if (flg == Qnil) flags = 0;
443 else flags = NUM2INT(flg);
444
445 GetOpenFile(sock, fptr);
446 if (rb_read_pending(fptr->f)) {
447 rb_raise(rb_eIOError, "recv for buffered IO");
448 }
449 fd = fileno(fptr->f);
450
451 slen = NUM2INT(len);
452 str = rb_tainted_str_new(0, slen);
453
454 retry:
455 rb_thread_wait_fd(fd);
456 TRAP_BEG;
457 slen = recvfrom(fd, RSTRING(str)->ptr, slen, flags, (struct sockaddr*)buf, &alen);
458 TRAP_END;
459
460 if (slen < 0) {
461 switch (errno) {
462 case EINTR:
463 rb_thread_schedule();
464 goto retry;
465 }
466 rb_sys_fail("recvfrom(2)");
467 }
468 if (slen < RSTRING(str)->len) {
469 RSTRING(str)->len = slen;
470 RSTRING(str)->ptr[slen] = '\0';
471 }
472 rb_obj_taint(str);
473 switch (from) {
474 case RECV_RECV:
475 return (VALUE)str;
476 case RECV_IP:
477 #if 0
478 if (alen != sizeof(struct sockaddr_in)) {
479 rb_raise(rb_eTypeError, "sockaddr size differs - should not happen");
480 }
481 #endif
482 return rb_assoc_new(str, ipaddr((struct sockaddr*)buf));
483 #ifdef HAVE_SYS_UN_H
484 case RECV_UNIX:
485 return rb_assoc_new(str, unixaddr((struct sockaddr_un*)buf));
486 #endif
487 case RECV_SOCKET:
488 return rb_assoc_new(str, rb_str_new(buf, alen));
489 default:
490 rb_bug("s_recvfrom called with bad value");
491 }
492 }
493
494 static VALUE
495 bsock_recv(argc, argv, sock)
496 int argc;
497 VALUE *argv;
498 VALUE sock;
499 {
500 return s_recvfrom(sock, argc, argv, RECV_RECV);
501 }
502
503 static VALUE
504 bsock_do_not_rev_lookup()
505 {
506 return do_not_reverse_lookup?Qtrue:Qfalse;
507 }
508
509 static VALUE
510 bsock_do_not_rev_lookup_set(self, val)
511 {
512 rb_secure(4);
513 do_not_reverse_lookup = RTEST(val);
514 return val;
515 }
516
517 static void
518 mkipaddr0(addr, buf, len)
519 struct sockaddr *addr;
520 char *buf;
521 size_t len;
522 {
523 int error;
524
525 error = getnameinfo(addr, SA_LEN(addr), buf, len, NULL, 0, NI_NUMERICHOST);
526 if (error) {
527 rb_raise(rb_eSocket, "getnameinfo: %s", gai_strerror(error));
528 }
529 }
530
531 static VALUE
532 mkipaddr(addr)
533 struct sockaddr *addr;
534 {
535 char buf[1024];
536
537 mkipaddr0(addr, buf, sizeof(buf));
538 return rb_str_new2(buf);
539 }
540
541 static void
542 mkinetaddr(host, buf, len)
543 long host;
544 char *buf;
545 size_t len;
546 {
547 struct sockaddr_in sin;
548
549 MEMZERO(&sin, struct sockaddr_in, 1);
550 sin.sin_family = AF_INET;
551 SET_SIN_LEN(&sin, sizeof(sin));
552 sin.sin_addr.s_addr = host;
553 mkipaddr0((struct sockaddr*)&sin, buf, len);
554 }
555
556 static int
557 str_isnumber(p)
558 const char *p;
559 {
560 char *ep;
561
562 if (!p || *p == '\0')
563 return 0;
564 ep = NULL;
565 (void)strtoul(p, &ep, 10);
566 if (ep && *ep == '\0')
567 return 1;
568 else
569 return 0;
570 }
571
572 static struct addrinfo*
573 sock_addrinfo(host, port, socktype, flags)
574 VALUE host, port;
575 int socktype, flags;
576 {
577 struct addrinfo hints, *hintsp, *res;
578 char *hostp, *portp;
579 int error;
580 char hbuf[1024], pbuf[16];
581
582 if (NIL_P(host)) {
583 hostp = NULL;
584 }
585 else if (rb_obj_is_kind_of(host, rb_cInteger)) {
586 long i = NUM2LONG(host);
587
588 mkinetaddr(htonl(i), hbuf, sizeof(hbuf));
589 hostp = hbuf;
590 }
591 else {
592 char *name;
593
594 SafeStringValue(host);
595 name = RSTRING(host)->ptr;
596 if (*name == 0 || (name[0] == '<' && strcmp(name, "<any>") == 0)) {
597 mkinetaddr(INADDR_ANY, hbuf, sizeof(hbuf));
598 }
599 else if (name[0] == '<' && strcmp(name, "<broadcast>") == 0) {
600 mkinetaddr(INADDR_BROADCAST, hbuf, sizeof(hbuf));
601 }
602 else if (strlen(name) >= sizeof(hbuf)) {
603 rb_raise(rb_eArgError, "hostname too long (%d)", strlen(name));
604 }
605 else {
606 strcpy(hbuf, name);
607 }
608 hostp = hbuf;
609 }
610 if (NIL_P(port)) {
611 portp = 0;
612 }
613 else if (FIXNUM_P(port)) {
614 snprintf(pbuf, sizeof(pbuf), "%d", FIX2INT(port));
615 portp = pbuf;
616 }
617 else {
618 SafeStringValue(port);
619 portp = RSTRING(port)->ptr;
620 }
621
622 if (socktype == 0 && flags == 0 && str_isnumber(portp)) {
623 socktype = SOCK_DGRAM;
624 }
625
626 hintsp = &hints;
627 MEMZERO(&hints, struct addrinfo, 1);
628 hints.ai_family = PF_UNSPEC;
629 hints.ai_protocol = 0;
630 hints.ai_socktype = socktype;
631 hints.ai_flags = flags;
632 error = getaddrinfo(hostp, portp, hintsp, &res);
633 if (error) {
634 if (hostp && hostp[strlen(hostp)-1] == '\n') {
635 rb_raise(rb_eSocket, "newline at the end of hostname");
636 }
637 rb_raise(rb_eSocket, "getaddrinfo: %s", gai_strerror(error));
638 }
639
640 return res;
641 }
642
643 static void
644 setipaddr(name, addr)
645 VALUE name;
646 struct sockaddr_storage *addr;
647 {
648 struct addrinfo *res = sock_addrinfo(name, Qnil, SOCK_STREAM, 0);
649
650
651 memcpy(addr, res->ai_addr, res->ai_addrlen);
652 freeaddrinfo(res);
653 }
654
655 static VALUE
656 ipaddr(sockaddr)
657 struct sockaddr *sockaddr;
658 {
659 VALUE family, port, addr1, addr2;
660 VALUE ary;
661 int error;
662 char hbuf[1024], pbuf[1024];
663
664 switch (sockaddr->sa_family) {
665 case AF_UNSPEC:
666 family = rb_str_new2("AF_UNSPEC");
667 break;
668 case AF_INET:
669 family = rb_str_new2("AF_INET");
670 break;
671 #ifdef INET6
672 case AF_INET6:
673 family = rb_str_new2("AF_INET6");
674 break;
675 #endif
676 #ifdef AF_LOCAL
677 case AF_LOCAL:
678 family = rb_str_new2("AF_LOCAL");
679 break;
680 #elif AF_UNIX
681 case AF_UNIX:
682 family = rb_str_new2("AF_UNIX");
683 break;
684 #endif
685 default:
686 sprintf(pbuf, "unknown:%d", sockaddr->sa_family);
687 family = rb_str_new2(pbuf);
688 break;
689 }
690 if (!do_not_reverse_lookup) {
691 error = getnameinfo(sockaddr, SA_LEN(sockaddr), hbuf, sizeof(hbuf),
692 NULL, 0, 0);
693 if (error) {
694 rb_raise(rb_eSocket, "getnameinfo: %s", gai_strerror(error));
695 }
696 addr1 = rb_str_new2(hbuf);
697 }
698 error = getnameinfo(sockaddr, SA_LEN(sockaddr), hbuf, sizeof(hbuf),
699 pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV);
700 if (error) {
701 rb_raise(rb_eSocket, "getnameinfo: %s", gai_strerror(error));
702 }
703 addr2 = rb_str_new2(hbuf);
704 if (do_not_reverse_lookup) {
705 addr1 = addr2;
706 }
707 port = INT2FIX(atoi(pbuf));
708 ary = rb_ary_new3(4, family, port, addr1, addr2);
709
710 return ary;
711 }
712
713 static int
714 ruby_socket(domain, type, proto)
715 int domain, type, proto;
716 {
717 int fd;
718
719 fd = socket(domain, type, proto);
720 if (fd < 0) {
721 if (errno == EMFILE || errno == ENFILE) {
722 rb_gc();
723 fd = socket(domain, type, proto);
724 }
725 }
726 return fd;
727 }
728
729 static void
730 thread_read_select(fd)
731 int fd;
732 {
733 fd_set fds;
734
735 FD_ZERO(&fds);
736 FD_SET(fd, &fds);
737 rb_thread_select(fd+1, &fds, 0, 0, 0);
738 }
739
740 static void
741 thread_write_select(fd)
742 int fd;
743 {
744 fd_set fds;
745
746 FD_ZERO(&fds);
747 FD_SET(fd, &fds);
748 rb_thread_select(fd+1, 0, &fds, 0, 0);
749 }
750
751 static int
752 ruby_connect(fd, sockaddr, len, socks)
753 int fd;
754 struct sockaddr *sockaddr;
755 int len;
756 int socks;
757 {
758 int status;
759 int mode;
760 #if defined __CYGWIN__
761 int wait_in_progress = -1;
762 #endif
763
764 #if defined(HAVE_FCNTL)
765 mode = fcntl(fd, F_GETFL, 0);
766
767 #ifdef O_NDELAY
768 # define NONBLOCKING O_NDELAY
769 #else
770 #ifdef O_NBIO
771 # define NONBLOCKING O_NBIO
772 #else
773 # define NONBLOCKING O_NONBLOCK
774 #endif
775 #endif
776 #ifdef SOCKS5
777 if (!socks)
778 #endif
779 fcntl(fd, F_SETFL, mode|NONBLOCKING);
780 #endif
781
782 for (;;) {
783 #if defined(SOCKS) && !defined(SOCKS5)
784 if (socks) {
785 status = Rconnect(fd, sockaddr, len);
786 }
787 else
788 #endif
789 {
790 status = connect(fd, sockaddr, len);
791 }
792 if (status < 0) {
793 switch (errno) {
794 case EAGAIN:
795 #ifdef EINPROGRESS
796 case EINPROGRESS:
797 #ifdef __CYGWIN__
798 case EALREADY:
799 wait_in_progress = 10;
800 #endif
801 #endif
802 thread_write_select(fd);
803 continue;
804
805 #if defined __CYGWIN__
806 case EINVAL:
807 if (wait_in_progress-- > 0) {
808 struct timeval tv = {0, 100000};
809 rb_thread_wait_for(tv);
810 continue;
811 }
812 break;
813 #endif
814
815 #ifdef EISCONN
816 case EISCONN:
817 status = 0;
818 errno = 0;
819 break;
820 #endif
821 default:
822 break;
823 }
824 }
825 #ifdef HAVE_FCNTL
826 fcntl(fd, F_SETFL, mode);
827 #endif
828 return status;
829 }
830 }
831
832 static void
833 load_addr_info(h, serv, type, res)
834 VALUE h, serv;
835 int type;
836 struct addrinfo **res;
837 {
838 char *host;
839 char pbuf[1024], *portp;
840 struct addrinfo hints;
841 int error;
842
843 if (!NIL_P(h)) {
844 SafeStringValue(h);
845 host = RSTRING(h)->ptr;
846 }
847 else {
848 host = NULL;
849 }
850 if (FIXNUM_P(serv)) {
851 snprintf(pbuf, sizeof(pbuf), "%ld", FIX2UINT(serv));
852 portp = pbuf;
853 }
854 else {
855 SafeStringValue(serv);
856 if (RSTRING(serv)->len >= sizeof(pbuf))
857 rb_raise(rb_eArgError, "servicename too long (%d)", RSTRING(serv)->len);
858 strcpy(pbuf, RSTRING(serv)->ptr);
859 portp = pbuf;
860 }
861 MEMZERO(&hints, struct addrinfo, 1);
862 hints.ai_family = PF_UNSPEC;
863 if (type == INET_SERVER) {
864 hints.ai_flags = AI_PASSIVE;
865 }
866 error = getaddrinfo(host, portp, &hints, res);
867 if (error) {
868 rb_raise(rb_eSocket, "getaddrinfo: %s", gai_strerror(error));
869 }
870 }
871
872 struct inetsock_arg
873 {
874 VALUE sock;
875 struct {
876 VALUE host, serv;
877 struct addrinfo *res;
878 } remote, local;
879 int type;
880 int fd;
881 };
882
883 static VALUE
884 inetsock_cleanup(arg)
885 struct inetsock_arg *arg;
886 {
887 if (arg->remote.res) {
888 freeaddrinfo(arg->remote.res);
889 arg->remote.res = 0;
890 }
891 if (arg->local.res) {
892 freeaddrinfo(arg->local.res);
893 arg->local.res = 0;
894 }
895 if (arg->fd >= 0) {
896 close(arg->fd);
897 }
898 return Qnil;
899 }
900
901 static VALUE
902 init_inetsock_internal(arg)
903 struct inetsock_arg *arg;
904 {
905 int type = arg->type;
906 struct addrinfo hints, *res;
907 int fd, status;
908 char *syscall;
909
910 arg->remote.res = sock_addrinfo(arg->remote.host, arg->remote.serv, SOCK_STREAM,
911 (type == INET_SERVER) ? AI_PASSIVE : 0);
912
913
914
915
916 if (type != INET_SERVER && (!NIL_P(arg->local.host) || !NIL_P(arg->local.serv))) {
917 arg->local.res = sock_addrinfo(arg->local.host, arg->local.serv, SOCK_STREAM, 0);
918 }
919
920 arg->fd = fd = -1;
921 for (res = arg->remote.res; res; res = res->ai_next) {
922 status = ruby_socket(res->ai_family,res->ai_socktype,res->ai_protocol);
923 syscall = "socket(2)";
924 fd = status;
925 if (fd < 0) {
926 continue;
927 }
928 arg->fd = fd;
929 if (type == INET_SERVER) {
930 #ifndef NT
931 status = 1;
932 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
933 (char*)&status, sizeof(status));
934 #endif
935 status = bind(fd, res->ai_addr, res->ai_addrlen);
936 syscall = "bind(2)";
937 }
938 else {
939 if (arg->local.res) {
940 status = bind(fd, arg->local.res->ai_addr, arg->local.res->ai_addrlen);
941 syscall = "bind(2)";
942 }
943
944 if (status >= 0) {
945 status = ruby_connect(fd, res->ai_addr, res->ai_addrlen,
946 (type == INET_SOCKS));
947 syscall = "connect(2)";
948 }
949 }
950
951 if (status < 0) {
952 close(fd);
953 arg->fd = fd = -1;
954 continue;
955 } else
956 break;
957 }
958 if (status < 0) {
959 rb_sys_fail(syscall);
960 }
961
962 arg->fd = -1;
963
964 if (type == INET_SERVER)
965 listen(fd, 5);
966
967
968 return init_sock(arg->sock, fd);
969 }
970
971 static VALUE
972 init_inetsock(sock, remote_host, remote_serv, local_host, local_serv, type)
973 VALUE sock, remote_host, remote_serv, local_host, local_serv;
974 int type;
975 {
976 struct inetsock_arg arg;
977 arg.sock = sock;
978 arg.remote.host = remote_host;
979 arg.remote.serv = remote_serv;
980 arg.remote.res = 0;
981 arg.local.host = local_host;
982 arg.local.serv = local_serv;
983 arg.local.res = 0;
984 arg.type = type;
985 arg.fd = -1;
986 return rb_ensure(init_inetsock_internal, (VALUE)&arg,
987 inetsock_cleanup, (VALUE)&arg);
988 }
989
990 static VALUE
991 tcp_init(argc, argv, sock)
992 int argc;
993 VALUE *argv;
994 VALUE sock;
995 {
996 VALUE remote_host, remote_serv;
997 VALUE local_host, local_serv;
998
999 int pcount = rb_scan_args(argc, argv, "22",
1000 &remote_host, &remote_serv,
1001 &local_host, &local_serv);
1002
1003 return init_inetsock(sock, remote_host, remote_serv,
1004 local_host, local_serv, INET_CLIENT);
1005 }
1006
1007 #ifdef SOCKS
1008 static VALUE
1009 socks_init(sock, host, serv)
1010 VALUE sock, host, serv;
1011 {
1012 static init = 0;
1013
1014 if (init == 0) {
1015 SOCKSinit("ruby");
1016 init = 1;
1017 }
1018
1019 return init_inetsock(class, host, serv, Qnil, Qnil, INET_SOCKS);
1020 }
1021
1022 #ifdef SOCKS5
1023 static VALUE
1024 socks_s_close(sock)
1025 VALUE sock;
1026 {
1027 OpenFile *fptr;
1028
1029 if (rb_safe_level() >= 4 && !OBJ_TAINTED(sock)) {
1030 rb_raise(rb_eSecurityError, "Insecure: can't close socket");
1031 }
1032 GetOpenFile(sock, fptr);
1033 shutdown(fileno(fptr->f), 2);
1034 shutdown(fileno(fptr->f2), 2);
1035 return rb_io_close(sock);
1036 }
1037 #endif
1038 #endif
1039
1040
1041
1042
1043
1044
1045 struct hostent*
1046 sock_hostbyname(host)
1047 VALUE host;
1048 {
1049 struct sockaddr_storage addr;
1050 struct hostent *h;
1051
1052 rb_secure(3);
1053 setipaddr(host, &addr);
1054 switch (addr.ss_family) {
1055 case AF_INET:
1056 {
1057 struct sockaddr_in *sin;
1058 sin = (struct sockaddr_in*)&addr;
1059 h = gethostbyaddr((char*)&sin->sin_addr,
1060 sizeof(sin->sin_addr),
1061 sin->sin_family);
1062 break;
1063 }
1064 #ifdef INET6
1065 case AF_INET6:
1066 {
1067 struct sockaddr_in6 *sin6;
1068 sin6 = (struct sockaddr_in6*)&addr;
1069 h = gethostbyaddr((char*)&sin6->sin6_addr,
1070 sizeof(sin6->sin6_addr),
1071 sin6->sin6_family);
1072 break;
1073 }
1074 #endif
1075 default:
1076 h = NULL;
1077 break;
1078 }
1079
1080 if (h == NULL) {
1081 #ifdef HAVE_HSTERROR
1082 extern int h_errno;
1083 rb_raise(rb_eSocket, "%s", (char*)hsterror(h_errno));
1084 #else
1085 rb_raise(rb_eSocket, "host not found");
1086 #endif
1087 }
1088 return h;
1089 }
1090
1091 static VALUE
1092 tcp_s_gethostbyname(obj, host)
1093 VALUE obj, host;
1094 {
1095 struct hostent *h = sock_hostbyname(host);
1096 VALUE ary, names;
1097 char **pch;
1098 size_t size;
1099
1100 ary = rb_ary_new();
1101 rb_ary_push(ary, rb_str_new2(h->h_name));
1102 names = rb_ary_new();
1103 rb_ary_push(ary, names);
1104 for (pch = h->h_aliases; *pch; pch++) {
1105 rb_ary_push(names, rb_str_new2(*pch));
1106 }
1107 rb_ary_push(ary, INT2NUM(h->h_addrtype));
1108 #ifdef h_addr
1109 for (pch = h->h_addr_list; *pch; pch++) {
1110 switch (h->h_length) {
1111 case 4: {
1112 struct sockaddr_in sin;
1113
1114 MEMZERO(&sin, struct sockaddr_in, 1);
1115 sin.sin_family = AF_INET;
1116 SET_SIN_LEN(&sin, sizeof(sin));
1117 memcpy((char*)&sin.sin_addr, *pch, h->h_length);
1118 rb_ary_push(ary, mkipaddr((struct sockaddr*)&sin));
1119 break;
1120 }
1121 #ifdef INET6
1122 case 8: {
1123 struct sockaddr_in6 sin6;
1124
1125 MEMZERO(&sin6, struct sockaddr_in6, 1);
1126 sin6.sin6_family = AF_INET6;
1127 #ifdef SIN6_LEN
1128 sin6.sin6_len = sizeof(sin6);
1129 #endif
1130 memcpy((char*)&sin6.sin6_addr, *pch, size);
1131 rb_ary_push(ary, mkipaddr((struct sockaddr*)&sin6));
1132 break;
1133 }
1134 #endif
1135 default:
1136 break;
1137 }
1138 }
1139 #else
1140 memcpy((char*)&addr.sin_addr, h->h_addr, h->h_length);
1141 rb_ary_push(ary, mkipaddr((struct sockaddr*)&addr));
1142 #endif
1143
1144 return ary;
1145 }
1146
1147 static VALUE
1148 tcp_svr_init(argc, argv, sock)
1149 int argc;
1150 VALUE *argv;
1151 VALUE sock;
1152 {
1153 VALUE arg1, arg2;
1154
1155 if (rb_scan_args(argc, argv, "11", &arg1, &arg2) == 2)
1156 return init_inetsock(sock, arg1, arg2, NULL, Qnil, INET_SERVER);
1157 else
1158 return init_inetsock(sock, Qnil, arg1, NULL, Qnil, INET_SERVER);
1159 }
1160
1161 static VALUE
1162 s_accept(klass, fd, sockaddr, len)
1163 VALUE klass;
1164 int fd;
1165 struct sockaddr *sockaddr;
1166 socklen_t *len;
1167 {
1168 int fd2;
1169 int retry = 0;
1170
1171 rb_secure(3);
1172 retry:
1173 rb_thread_wait_fd(fd);
1174 #if defined(_nec_ews)
1175 fd2 = accept(fd, sockaddr, len);
1176 #else
1177 TRAP_BEG;
1178 fd2 = accept(fd, sockaddr, len);
1179 TRAP_END;
1180 #endif
1181 if (fd2 < 0) {
1182 switch (errno) {
1183 case EMFILE:
1184 case ENFILE:
1185 if (retry) break;
1186 rb_gc();
1187 retry = 1;
1188 goto retry;
1189 case EINTR:
1190 rb_thread_schedule();
1191 goto retry;
1192 }
1193 rb_sys_fail(0);
1194 }
1195 if (!klass) return INT2NUM(fd2);
1196 return init_sock(rb_obj_alloc(klass), fd2);
1197 }
1198
1199 static VALUE
1200 tcp_accept(sock)
1201 VALUE sock;
1202 {
1203 OpenFile *fptr;
1204 struct sockaddr_storage from;
1205 socklen_t fromlen;
1206
1207 GetOpenFile(sock, fptr);
1208 fromlen = sizeof(from);
1209 return s_accept(rb_cTCPSocket, fileno(fptr->f),
1210 (struct sockaddr*)&from, &fromlen);
1211 }
1212
1213 static VALUE
1214 tcp_sysaccept(sock)
1215 VALUE sock;
1216 {
1217 OpenFile *fptr;
1218 struct sockaddr_storage from;
1219 socklen_t fromlen;
1220
1221 GetOpenFile(sock, fptr);
1222 fromlen = sizeof(from);
1223 return s_accept(0, fileno(fptr->f), (struct sockaddr*)&from, &fromlen);
1224 }
1225
1226 #ifdef HAVE_SYS_UN_H
1227 struct unixsock_arg {
1228 struct sockaddr_un *sockaddr;
1229 int fd;
1230 };
1231
1232 static VALUE
1233 unixsock_connect_internal(arg)
1234 struct unixsock_arg *arg;
1235 {
1236 return (VALUE)ruby_connect(arg->fd, arg->sockaddr, sizeof(*arg->sockaddr),
1237 0);
1238 }
1239
1240 static VALUE
1241 init_unixsock(sock, path, server)
1242 VALUE sock;
1243 VALUE path;
1244 int server;
1245 {
1246 struct sockaddr_un sockaddr;
1247 int fd, status;
1248 OpenFile *fptr;
1249
1250 SafeStringValue(path);
1251 fd = ruby_socket(AF_UNIX, SOCK_STREAM, 0);
1252 if (fd < 0) {
1253 rb_sys_fail("socket(2)");
1254 }
1255
1256 MEMZERO(&sockaddr, struct sockaddr_un, 1);
1257 sockaddr.sun_family = AF_UNIX;
1258 strncpy(sockaddr.sun_path, RSTRING(path)->ptr, sizeof(sockaddr.sun_path)-1);
1259 sockaddr.sun_path[sizeof(sockaddr.sun_path)-1] = '\0';
1260
1261 if (server) {
1262 status = bind(fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr));
1263 }
1264 else {
1265 int prot;
1266 struct unixsock_arg arg;
1267 arg.sockaddr = &sockaddr;
1268 arg.fd = fd;
1269 status = rb_protect(unixsock_connect_internal, (VALUE)&arg, &prot);
1270 if (prot) {
1271 close(fd);
1272 rb_jump_tag(prot);
1273 }
1274 }
1275
1276 if (status < 0) {
1277 close(fd);
1278 rb_sys_fail(sockaddr.sun_path);
1279 }
1280
1281 if (server) listen(fd, 5);
1282
1283 init_sock(sock, fd);
1284 GetOpenFile(sock, fptr);
1285 fptr->path = strdup(RSTRING(path)->ptr);
1286
1287 return sock;
1288 }
1289 #endif
1290
1291 static VALUE
1292 ip_addr(sock)
1293 VALUE sock;
1294 {
1295 OpenFile *fptr;
1296 struct sockaddr_storage addr;
1297 socklen_t len = sizeof addr;
1298
1299 GetOpenFile(sock, fptr);
1300
1301 if (getsockname(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0)
1302 rb_sys_fail("getsockname(2)");
1303 return ipaddr((struct sockaddr*)&addr);
1304 }
1305
1306 static VALUE
1307 ip_peeraddr(sock)
1308 VALUE sock;
1309 {
1310 OpenFile *fptr;
1311 struct sockaddr_storage addr;
1312 socklen_t len = sizeof addr;
1313
1314 GetOpenFile(sock, fptr);
1315
1316 if (getpeername(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0)
1317 rb_sys_fail("getpeername(2)");
1318 return ipaddr((struct sockaddr*)&addr);
1319 }
1320
1321 static VALUE
1322 ip_recvfrom(argc, argv, sock)
1323 int argc;
1324 VALUE *argv;
1325 VALUE sock;
1326 {
1327 return s_recvfrom(sock, argc, argv, RECV_IP);
1328 }
1329
1330 static VALUE
1331 ip_s_getaddress(obj, host)
1332 VALUE obj, host;
1333 {
1334 struct sockaddr_storage addr;
1335
1336 setipaddr(host, &addr);
1337 return mkipaddr((struct sockaddr*)&addr);
1338 }
1339
1340 static VALUE
1341 udp_init(argc, argv, sock)
1342 int argc;
1343 VALUE *argv;
1344 VALUE sock;
1345 {
1346 VALUE arg;
1347 int socktype = AF_INET;
1348 int fd;
1349
1350 rb_secure(3);
1351 if (rb_scan_args(argc, argv, "01", &arg) == 1) {
1352 socktype = NUM2INT(arg);
1353 }
1354 fd = ruby_socket(socktype, SOCK_DGRAM, 0);
1355 if (fd < 0) {
1356 rb_sys_fail("socket(2) - udp");
1357 }
1358
1359 return init_sock(sock, fd);
1360 }
1361
1362 struct udp_arg
1363 {
1364 struct addrinfo *res;
1365 int fd;
1366 };
1367
1368 static VALUE
1369 udp_connect_internal(arg)
1370 struct udp_arg *arg;
1371 {
1372 int fd = arg->fd;
1373 struct addrinfo *res;
1374
1375 for (res = arg->res; res; res = res->ai_next) {
1376 if (ruby_connect(fd, res->ai_addr, res->ai_addrlen, 0) >= 0) {
1377 return Qtrue;
1378 }
1379 }
1380 return Qfalse;
1381 }
1382
1383 static VALUE
1384 udp_connect(sock, host, port)
1385 VALUE sock, host, port;
1386 {
1387 OpenFile *fptr;
1388 int fd;
1389 struct udp_arg arg;
1390 VALUE ret;
1391
1392 rb_secure(3);
1393 GetOpenFile(sock, fptr);
1394 arg.res = sock_addrinfo(host, port, SOCK_DGRAM, 0);
1395 arg.fd = fileno(fptr->f);
1396 ret = rb_ensure(udp_connect_internal, (VALUE)&arg,
1397 RUBY_METHOD_FUNC(freeaddrinfo), (VALUE)arg.res);
1398 if (!ret) rb_sys_fail("connect(2)");
1399 return INT2FIX(0);
1400 }
1401
1402 static VALUE
1403 udp_bind(sock, host, port)
1404 VALUE sock, host, port;
1405 {
1406 OpenFile *fptr;
1407 struct addrinfo *res0, *res;
1408
1409 rb_secure(3);
1410 GetOpenFile(sock, fptr);
1411 res0 = sock_addrinfo(host, port, SOCK_DGRAM, 0);
1412 for (res = res0; res; res = res->ai_next) {
1413 if (bind(fileno(fptr->f), res->ai_addr, res->ai_addrlen) < 0) {
1414 continue;
1415 }
1416 freeaddrinfo(res0);
1417 return INT2FIX(0);
1418 }
1419 freeaddrinfo(res0);
1420 rb_sys_fail("bind(2)");
1421 return INT2FIX(0);
1422 }
1423
1424 static VALUE
1425 udp_send(argc, argv, sock)
1426 int argc;
1427 VALUE *argv;
1428 VALUE sock;
1429 {
1430 VALUE mesg, flags, host, port;
1431 OpenFile *fptr;
1432 FILE *f;
1433 int n;
1434 struct addrinfo *res0, *res;
1435
1436 if (argc == 2 || argc == 3) {
1437 return bsock_send(argc, argv, sock);
1438 }
1439 rb_secure(4);
1440 rb_scan_args(argc, argv, "4", &mesg, &flags, &host, &port);
1441
1442 GetOpenFile(sock, fptr);
1443 res0 = sock_addrinfo(host, port, SOCK_DGRAM, 0);
1444 f = GetWriteFile(fptr);
1445 StringValue(mesg);
1446 for (res = res0; res; res = res->ai_next) {
1447 retry:
1448 n = sendto(fileno(f), RSTRING(mesg)->ptr, RSTRING(mesg)->len, NUM2INT(flags),
1449 res->ai_addr, res->ai_addrlen);
1450 if (n >= 0) {
1451 freeaddrinfo(res0);
1452 return INT2FIX(n);
1453 }
1454 switch (errno) {
1455 case EINTR:
1456 rb_thread_schedule();
1457 goto retry;
1458 }
1459 }
1460 freeaddrinfo(res0);
1461 rb_sys_fail("sendto(2)");
1462 return INT2FIX(n);
1463 }
1464
1465 #ifdef HAVE_SYS_UN_H
1466 static VALUE
1467 unix_init(sock, path)
1468 VALUE sock, path;
1469 {
1470 return init_unixsock(sock, path, 0);
1471 }
1472
1473 static VALUE
1474 unix_path(sock)
1475 VALUE sock;
1476 {
1477 OpenFile *fptr;
1478
1479 GetOpenFile(sock, fptr);
1480 if (fptr->path == 0) {
1481 struct sockaddr_un addr;
1482 socklen_t len = sizeof(addr);
1483 if (getsockname(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0)
1484 rb_sys_fail(0);
1485 fptr->path = strdup(addr.sun_path);
1486 }
1487 return rb_str_new2(fptr->path);
1488 }
1489
1490 static VALUE
1491 unix_svr_s_open(klass, path)
1492 VALUE klass, path;
1493 {
1494 return init_unixsock(rb_obj_alloc(klass), path, 1);
1495 }
1496
1497 static VALUE
1498 unix_svr_init(sock, path)
1499 VALUE sock, path;
1500 {
1501 return init_unixsock(sock, path, 1);
1502 }
1503
1504 static VALUE
1505 unix_recvfrom(argc, argv, sock)
1506 int argc;
1507 VALUE *argv;
1508 VALUE sock;
1509 {
1510 return s_recvfrom(sock, argc, argv, RECV_UNIX);
1511 }
1512
1513 static VALUE
1514 unix_send_io(sock, val)
1515 VALUE sock, val;
1516 {
1517 #if defined(HAVE_ST_MSG_CONTROL) || defined(HAVE_ST_MSG_ACCRIGHTS)
1518 int fd;
1519 OpenFile *fptr;
1520 struct msghdr msg;
1521 struct iovec vec[1];
1522 char buf[1];
1523
1524 #if defined(HAVE_ST_MSG_CONTROL)
1525 struct {
1526 struct cmsghdr hdr;
1527 int fd;
1528 } cmsg;
1529 #endif
1530
1531 if (rb_obj_is_kind_of(val, rb_cIO)) {
1532 OpenFile *valfptr;
1533 GetOpenFile(val, valfptr);
1534 fd = fileno(valfptr->f);
1535 }
1536 else if (FIXNUM_P(val)) {
1537 fd = FIX2INT(val);
1538 }
1539 else {
1540 rb_raise(rb_eTypeError, "IO nor file descriptor");
1541 }
1542
1543 GetOpenFile(sock, fptr);
1544
1545 msg.msg_name = NULL;
1546 msg.msg_namelen = 0;
1547
1548
1549 buf[0] = '\0';
1550 vec[0].iov_base = buf;
1551 vec[0].iov_len = 1;
1552 msg.msg_iov = vec;
1553 msg.msg_iovlen = 1;
1554
1555 #if defined(HAVE_ST_MSG_CONTROL)
1556 msg.msg_control = (caddr_t)&cmsg;
1557 msg.msg_controllen = sizeof(struct cmsghdr) + sizeof(int);
1558 msg.msg_flags = 0;
1559 cmsg.hdr.cmsg_len = sizeof(struct cmsghdr) + sizeof(int);
1560 cmsg.hdr.cmsg_level = SOL_SOCKET;
1561 cmsg.hdr.cmsg_type = SCM_RIGHTS;
1562 cmsg.fd = fd;
1563 #else
1564 msg.msg_accrights = (caddr_t)&fd;
1565 msg.msg_accrightslen = sizeof(fd);
1566 #endif
1567
1568 if (sendmsg(fileno(fptr->f), &msg, 0) == -1)
1569 rb_sys_fail("sendmsg(2)");
1570
1571 return Qnil;
1572 #else
1573 rb_notimplement();
1574 #endif
1575 }
1576
1577 static VALUE
1578 unix_recv_io(argc, argv, sock)
1579 int argc;
1580 VALUE *argv;
1581 VALUE sock;
1582 {
1583 #if defined(HAVE_ST_MSG_CONTROL) || defined(HAVE_ST_MSG_ACCRIGHTS)
1584 VALUE klass, mode;
1585 OpenFile *fptr;
1586 struct msghdr msg;
1587 struct iovec vec[2];
1588 char buf[1];
1589
1590 int fd;
1591 #if defined(HAVE_ST_MSG_CONTROL)
1592 struct {
1593 struct cmsghdr hdr;
1594 int fd;
1595 } cmsg;
1596 #endif
1597
1598 rb_scan_args(argc, argv, "02", &klass, &mode);
1599 if (argc == 0)
1600 klass = rb_cIO;
1601 if (argc <= 1)
1602 mode = Qnil;
1603
1604 GetOpenFile(sock, fptr);
1605
1606 thread_read_select(fileno(fptr->f));
1607
1608 msg.msg_name = NULL;
1609 msg.msg_namelen = 0;
1610
1611 vec[0].iov_base = buf;
1612 vec[0].iov_len = sizeof(buf);
1613 msg.msg_iov = vec;
1614 msg.msg_iovlen = 1;
1615
1616 #if defined(HAVE_ST_MSG_CONTROL)
1617 msg.msg_control = (caddr_t)&cmsg;
1618 msg.msg_controllen = sizeof(struct cmsghdr) + sizeof(int);
1619 msg.msg_flags = 0;
1620 cmsg.hdr.cmsg_len = sizeof(struct cmsghdr) + sizeof(int);
1621 cmsg.hdr.cmsg_level = SOL_SOCKET;
1622 cmsg.hdr.cmsg_type = SCM_RIGHTS;
1623 cmsg.fd = -1;
1624 #else
1625 msg.msg_accrights = (caddr_t)&fd;
1626 msg.msg_accrightslen = sizeof(fd);
1627 fd = -1;
1628 #endif
1629
1630 if (recvmsg(fileno(fptr->f), &msg, 0) == -1)
1631 rb_sys_fail("recvmsg(2)");
1632
1633 if (
1634 #if defined(HAVE_ST_MSG_CONTROL)
1635 msg.msg_controllen != sizeof(struct cmsghdr) + sizeof(int) ||
1636 cmsg.hdr.cmsg_len != sizeof(struct cmsghdr) + sizeof(int) ||
1637 cmsg.hdr.cmsg_level != SOL_SOCKET ||
1638 cmsg.hdr.cmsg_type != SCM_RIGHTS
1639 #else
1640 msg.msg_accrightslen != sizeof(fd)
1641 #endif
1642 ) {
1643 rb_raise(rb_eSocket, "File descriptor was not passed");
1644 }
1645
1646 #if defined(HAVE_ST_MSG_CONTROL)
1647 fd = cmsg.fd;
1648 #endif
1649
1650 if (klass == Qnil)
1651 return INT2FIX(fd);
1652 else {
1653 static ID for_fd = 0;
1654 int ff_argc;
1655 VALUE ff_argv[2];
1656 if (!for_fd)
1657 for_fd = rb_intern("for_fd");
1658 ff_argc = mode == Qnil ? 1 : 2;
1659 ff_argv[0] = INT2FIX(fd);
1660 ff_argv[1] = mode;
1661 return rb_funcall2(klass, for_fd, ff_argc, ff_argv);
1662 }
1663 #else
1664 rb_notimplement();
1665 #endif
1666 }
1667
1668 static VALUE
1669 unix_accept(sock)
1670 VALUE sock;
1671 {
1672 OpenFile *fptr;
1673 struct sockaddr_un from;
1674 socklen_t fromlen;
1675
1676 GetOpenFile(sock, fptr);
1677 fromlen = sizeof(struct sockaddr_un);
1678 return s_accept(rb_cUNIXSocket, fileno(fptr->f),
1679 (struct sockaddr*)&from, &fromlen);
1680 }
1681
1682 static VALUE
1683 unix_sysaccept(sock)
1684 VALUE sock;
1685 {
1686 OpenFile *fptr;
1687 struct sockaddr_un from;
1688 socklen_t fromlen;
1689
1690 GetOpenFile(sock, fptr);
1691 fromlen = sizeof(struct sockaddr_un);
1692 return s_accept(0, fileno(fptr->f), (struct sockaddr*)&from, &fromlen);
1693 }
1694
1695 static VALUE
1696 unixaddr(sockaddr)
1697 struct sockaddr_un *sockaddr;
1698 {
1699 return rb_assoc_new(rb_str_new2("AF_UNIX"),
1700 rb_str_new2(sockaddr->sun_path));
1701 }
1702
1703 static VALUE
1704 unix_addr(sock)
1705 VALUE sock;
1706 {
1707 OpenFile *fptr;
1708 struct sockaddr_un addr;
1709 socklen_t len = sizeof addr;
1710
1711 GetOpenFile(sock, fptr);
1712
1713 if (getsockname(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0)
1714 rb_sys_fail("getsockname(2)");
1715 if (len == 0)
1716 addr.sun_path[0] = '\0';
1717 return unixaddr(&addr);
1718 }
1719
1720 static VALUE
1721 unix_peeraddr(sock)
1722 VALUE sock;
1723 {
1724 OpenFile *fptr;
1725 struct sockaddr_un addr;
1726 socklen_t len = sizeof addr;
1727
1728 GetOpenFile(sock, fptr);
1729
1730 if (getpeername(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0)
1731 rb_sys_fail("getsockname(2)");
1732 if (len == 0)
1733 addr.sun_path[0] = '\0';
1734 return unixaddr(&addr);
1735 }
1736 #endif
1737
1738 static void
1739 setup_domain_and_type(domain, dv, type, tv)
1740 VALUE domain, type;
1741 int *dv, *tv;
1742 {
1743 char *ptr;
1744
1745 if (TYPE(domain) == T_STRING) {
1746 SafeStringValue(domain);
1747 ptr = RSTRING(domain)->ptr;
1748 if (strcmp(ptr, "AF_INET") == 0)
1749 *dv = AF_INET;
1750 #ifdef AF_UNIX
1751 else if (strcmp(ptr, "AF_UNIX") == 0)
1752 *dv = AF_UNIX;
1753 #endif
1754 #ifdef AF_ISO
1755 else if (strcmp(ptr, "AF_ISO") == 0)
1756 *dv = AF_ISO;
1757 #endif
1758 #ifdef AF_NS
1759 else if (strcmp(ptr, "AF_NS") == 0)
1760 *dv = AF_NS;
1761 #endif
1762 #ifdef AF_IMPLINK
1763 else if (strcmp(ptr, "AF_IMPLINK") == 0)
1764 *dv = AF_IMPLINK;
1765 #endif
1766 #ifdef PF_INET
1767 else if (strcmp(ptr, "PF_INET") == 0)
1768 *dv = PF_INET;
1769 #endif
1770 #ifdef PF_UNIX
1771 else if (strcmp(ptr, "PF_UNIX") == 0)
1772 *dv = PF_UNIX;
1773 #endif
1774 #ifdef PF_IMPLINK
1775 else if (strcmp(ptr, "PF_IMPLINK") == 0)
1776 *dv = PF_IMPLINK;
1777 else if (strcmp(ptr, "AF_IMPLINK") == 0)
1778 *dv = AF_IMPLINK;
1779 #endif
1780 #ifdef PF_AX25
1781 else if (strcmp(ptr, "PF_AX25") == 0)
1782 *dv = PF_AX25;
1783 #endif
1784 #ifdef PF_IPX
1785 else if (strcmp(ptr, "PF_IPX") == 0)
1786 *dv = PF_IPX;
1787 #endif
1788 else
1789 rb_raise(rb_eSocket, "Unknown socket domain %s", ptr);
1790 }
1791 else {
1792 *dv = NUM2INT(domain);
1793 }
1794 if (TYPE(type) == T_STRING) {
1795 SafeStringValue(type);
1796 ptr = RSTRING(type)->ptr;
1797 if (strcmp(ptr, "SOCK_STREAM") == 0)
1798 *tv = SOCK_STREAM;
1799 else if (strcmp(ptr, "SOCK_DGRAM") == 0)
1800 *tv = SOCK_DGRAM;
1801 #ifdef SOCK_RAW
1802 else if (strcmp(ptr, "SOCK_RAW") == 0)
1803 *tv = SOCK_RAW;
1804 #endif
1805 #ifdef SOCK_SEQPACKET
1806 else if (strcmp(ptr, "SOCK_SEQPACKET") == 0)
1807 *tv = SOCK_SEQPACKET;
1808 #endif
1809 #ifdef SOCK_RDM
1810 else if (strcmp(ptr, "SOCK_RDM") == 0)
1811 *tv = SOCK_RDM;
1812 #endif
1813 #ifdef SOCK_PACKET
1814 else if (strcmp(ptr, "SOCK_PACKET") == 0)
1815 *tv = SOCK_PACKET;
1816 #endif
1817 else
1818 rb_raise(rb_eSocket, "Unknown socket type %s", ptr);
1819 }
1820 else {
1821 *tv = NUM2INT(type);
1822 }
1823 }
1824
1825 static VALUE
1826 sock_init(sock, domain, type, protocol)
1827 VALUE sock, domain, type, protocol;
1828 {
1829 int fd;
1830 int d, t;
1831
1832 rb_secure(3);
1833 setup_domain_and_type(domain, &d, type, &t);
1834 fd = ruby_socket(d, t, NUM2INT(protocol));
1835 if (fd < 0) rb_sys_fail("socket(2)");
1836
1837 return init_sock(sock, fd);
1838 }
1839
1840 static VALUE
1841 sock_s_socketpair(klass, domain, type, protocol)
1842 VALUE klass, domain, type, protocol;
1843 {
1844 #if !defined(NT) && !defined(__BEOS__) && !defined(__EMX__) && !defined(__QNXNTO__)
1845 int d, t, sp[2];
1846
1847 setup_domain_and_type(domain, &d, type, &t);
1848 again:
1849 if (socketpair(d, t, NUM2INT(protocol), sp) < 0) {
1850 if (errno == EMFILE || errno == ENFILE) {
1851 rb_gc();
1852 goto again;
1853 }
1854 rb_sys_fail("socketpair(2)");
1855 }
1856
1857 return rb_assoc_new(init_sock(rb_obj_alloc(klass), sp[0]),
1858 init_sock(rb_obj_alloc(klass), sp[1]));
1859 #else
1860 rb_notimplement();
1861 #endif
1862 }
1863
1864 #ifdef HAVE_SYS_UN_H
1865 static VALUE
1866 unix_s_socketpair(argc, argv, klass)
1867 int argc;
1868 VALUE *argv;
1869 VALUE klass;
1870 {
1871 VALUE domain, type, protocol;
1872 domain = INT2FIX(PF_UNIX);
1873
1874 rb_scan_args(argc, argv, "02", &type, &protocol);
1875 if (argc == 0)
1876 type = INT2FIX(SOCK_STREAM);
1877 if (argc <= 1)
1878 protocol = INT2FIX(0);
1879
1880 return sock_s_socketpair(klass, domain, type, protocol);
1881 }
1882 #endif
1883
1884 static VALUE
1885 sock_connect(sock, addr)
1886 VALUE sock, addr;
1887 {
1888 OpenFile *fptr;
1889 int fd;
1890
1891 StringValue(addr);
1892 rb_str_modify(addr);
1893
1894 GetOpenFile(sock, fptr);
1895 fd = fileno(fptr->f);
1896 if (ruby_connect(fd, (struct sockaddr*)RSTRING(addr)->ptr, RSTRING(addr)->len, 0) < 0) {
1897 rb_sys_fail("connect(2)");
1898 }
1899
1900 return INT2FIX(0);
1901 }
1902
1903 static VALUE
1904 sock_bind(sock, addr)
1905 VALUE sock, addr;
1906 {
1907 OpenFile *fptr;
1908
1909 StringValue(addr);
1910 rb_str_modify(addr);
1911
1912 GetOpenFile(sock, fptr);
1913 if (bind(fileno(fptr->f), (struct sockaddr*)RSTRING(addr)->ptr, RSTRING(addr)->len) < 0)
1914 rb_sys_fail("bind(2)");
1915
1916 return INT2FIX(0);
1917 }
1918
1919 static VALUE
1920 sock_listen(sock, log)
1921 VALUE sock, log;
1922 {
1923 OpenFile *fptr;
1924
1925 rb_secure(4);
1926 GetOpenFile(sock, fptr);
1927 if (listen(fileno(fptr->f), NUM2INT(log)) < 0)
1928 rb_sys_fail("listen(2)");
1929
1930 return INT2FIX(0);
1931 }
1932
1933 static VALUE
1934 sock_recvfrom(argc, argv, sock)
1935 int argc;
1936 VALUE *argv;
1937 VALUE sock;
1938 {
1939 return s_recvfrom(sock, argc, argv, RECV_SOCKET);
1940 }
1941
1942 static VALUE
1943 sock_accept(sock)
1944 VALUE sock;
1945 {
1946 OpenFile *fptr;
1947 VALUE sock2;
1948 char buf[1024];
1949 socklen_t len = sizeof buf;
1950
1951 GetOpenFile(sock, fptr);
1952 sock2 = s_accept(rb_cSocket,fileno(fptr->f),(struct sockaddr*)buf,&len);
1953
1954 return rb_assoc_new(sock2, rb_str_new(buf, len));
1955 }
1956
1957 static VALUE
1958 sock_sysaccept(sock)
1959 VALUE sock;
1960 {
1961 OpenFile *fptr;
1962 VALUE sock2;
1963 char buf[1024];
1964 socklen_t len = sizeof buf;
1965
1966 GetOpenFile(sock, fptr);
1967 sock2 = s_accept(0,fileno(fptr->f),(struct sockaddr*)buf,&len);
1968
1969 return rb_assoc_new(sock2, rb_str_new(buf, len));
1970 }
1971
1972 #ifdef HAVE_GETHOSTNAME
1973 static VALUE
1974 sock_gethostname(obj)
1975 VALUE obj;
1976 {
1977 char buf[1024];
1978
1979 rb_secure(3);
1980 if (gethostname(buf, (int)sizeof buf - 1) < 0)
1981 rb_sys_fail("gethostname");
1982
1983 buf[sizeof buf - 1] = '\0';
1984 return rb_str_new2(buf);
1985 }
1986 #else
1987 #ifdef HAVE_UNAME
1988
1989 #include <sys/utsname.h>
1990
1991 static VALUE
1992 sock_gethostname(obj)
1993 VALUE obj;
1994 {
1995 struct utsname un;
1996
1997 rb_secure(3);
1998 uname(&un);
1999 return rb_str_new2(un.nodename);
2000 }
2001 #else
2002 static VALUE
2003 sock_gethostname(obj)
2004 VALUE obj;
2005 {
2006 rb_notimplement();
2007 }
2008 #endif
2009 #endif
2010
2011 static VALUE
2012 sock_mkhostent(h)
2013 struct hostent *h;
2014 {
2015 char **pch;
2016 VALUE ary, names;
2017
2018 if (h == NULL) {
2019 #ifdef HAVE_HSTRERROR
2020 extern int h_errno;
2021 rb_raise(rb_eSocket, "%s", (char*)hstrerror(h_errno));
2022 #else
2023 rb_raise(rb_eSocket, "host not found");
2024 #endif
2025 }
2026 ary = rb_ary_new();
2027 rb_ary_push(ary, rb_str_new2(h->h_name));
2028 names = rb_ary_new();
2029 rb_ary_push(ary, names);
2030 for (pch = h->h_aliases; *pch; pch++) {
2031 rb_ary_push(names, rb_str_new2(*pch));
2032 }
2033 rb_ary_push(ary, INT2NUM(h->h_addrtype));
2034 #ifdef h_addr
2035 for (pch = h->h_addr_list; *pch; pch++) {
2036 rb_ary_push(ary, rb_str_new(*pch, h->h_length));
2037 }
2038 #else
2039 rb_ary_push(ary, rb_str_new(h->h_addr, h->h_length));
2040 #endif
2041
2042 return ary;
2043 }
2044
2045 static VALUE
2046 mkaddrinfo(res0)
2047 struct addrinfo *res0;
2048 {
2049 VALUE base, ary;
2050 struct addrinfo *res;
2051
2052 if (res0 == NULL) {
2053 rb_raise(rb_eSocket, "host not found");
2054 }
2055 base = rb_ary_new();
2056 for (res = res0; res; res = res->ai_next) {
2057 ary = ipaddr(res->ai_addr);
2058 rb_ary_push(ary, INT2FIX(res->ai_family));
2059 rb_ary_push(ary, INT2FIX(res->ai_socktype));
2060 rb_ary_push(ary, INT2FIX(res->ai_protocol));
2061 rb_ary_push(base, ary);
2062 }
2063 return base;
2064 }
2065
2066 static VALUE
2067 sock_s_gethostbyname(obj, host)
2068 VALUE obj, host;
2069 {
2070 return sock_mkhostent(sock_hostbyname(host));
2071 }
2072
2073 static VALUE
2074 sock_s_gethostbyaddr(argc, argv)
2075 int argc;
2076 VALUE *argv;
2077 {
2078 VALUE addr, type;
2079 struct hostent *h;
2080 struct sockaddr *sa;
2081 int t = AF_INET;
2082
2083 rb_scan_args(argc, argv, "11", &addr, &type);
2084 sa = (struct sockaddr*)StringValuePtr(addr);
2085 if (!NIL_P(type)) {
2086 t = NUM2INT(type);
2087 }
2088 #ifdef INET6
2089 else if (RSTRING(addr)->len == 16) {
2090 t = AF_INET6;
2091 }
2092 #endif
2093 h = gethostbyaddr(RSTRING(addr)->ptr, RSTRING(addr)->len, t);
2094
2095 return sock_mkhostent(h);
2096 }
2097
2098 static VALUE
2099 sock_s_getservbyaname(argc, argv)
2100 int argc;
2101 VALUE *argv;
2102 {
2103 VALUE service, protocol;
2104 char *proto;
2105 struct servent *sp;
2106 int port;
2107
2108 rb_scan_args(argc, argv, "11", &service, &protocol);
2109 if (NIL_P(protocol)) proto = "tcp";
2110 else proto = StringValuePtr(protocol);
2111
2112 StringValue(service);
2113 sp = getservbyname(RSTRING(service)->ptr, proto);
2114 if (sp) {
2115 port = ntohs(sp->s_port);
2116 }
2117 else {
2118 char *s = RSTRING(service)->ptr;
2119 char *end;
2120
2121 port = strtoul(s, &end, 0);
2122 if (*end != '\0') {
2123 rb_raise(rb_eSocket, "no such service %s/%s", s, proto);
2124 }
2125 }
2126 return INT2FIX(port);
2127 }
2128
2129 static VALUE
2130 sock_s_getaddrinfo(argc, argv)
2131 int argc;
2132 VALUE *argv;
2133 {
2134 VALUE host, port, family, socktype, protocol, flags, ret;
2135 char hbuf[1024], pbuf[1024];
2136 char *hptr, *pptr, *ap;
2137 struct addrinfo hints, *res;
2138 int error;
2139
2140 host = port = family = socktype = protocol = flags = Qnil;
2141 rb_scan_args(argc, argv, "24", &host, &port, &family, &socktype, &protocol, &flags);
2142 if (NIL_P(host)) {
2143 hptr = NULL;
2144 }
2145 else {
2146 strncpy(hbuf, StringValuePtr(host), sizeof(hbuf));
2147 hbuf[sizeof(hbuf) - 1] = '\0';
2148 hptr = hbuf;
2149 }
2150 if (NIL_P(port)) {
2151 pptr = NULL;
2152 }
2153 else if (FIXNUM_P(port)) {
2154 snprintf(pbuf, sizeof(pbuf), "%ld", FIX2INT(port));
2155 pptr = pbuf;
2156 }
2157 else {
2158 strncpy(pbuf, StringValuePtr(port), sizeof(pbuf));
2159 pbuf[sizeof(pbuf) - 1] = '\0';
2160 pptr = pbuf;
2161 }
2162
2163 MEMZERO(&hints, struct addrinfo, 1);
2164 if (NIL_P(family)) {
2165 hints.ai_family = PF_UNSPEC;
2166 }
2167 else if (FIXNUM_P(family)) {
2168 hints.ai_family = FIX2INT(family);
2169 }
2170 else if ((ap = StringValuePtr(family)) != 0) {
2171 if (strcmp(ap, "AF_INET") == 0) {
2172 hints.ai_family = PF_INET;
2173 }
2174 #ifdef INET6
2175 else if (strcmp(ap, "AF_INET6") == 0) {
2176 hints.ai_family = PF_INET6;
2177 }
2178 #endif
2179 }
2180
2181 if (!NIL_P(socktype)) {
2182 hints.ai_socktype = NUM2INT(socktype);
2183 }
2184 if (!NIL_P(protocol)) {
2185 hints.ai_protocol = NUM2INT(protocol);
2186 }
2187 if (!NIL_P(flags)) {
2188 hints.ai_flags = NUM2INT(flags);
2189 }
2190 error = getaddrinfo(hptr, pptr, &hints, &res);
2191 if (error) {
2192 rb_raise(rb_eSocket, "getaddrinfo: %s", gai_strerror(error));
2193 }
2194
2195 ret = mkaddrinfo(res);
2196 freeaddrinfo(res);
2197 return ret;
2198 }
2199
2200 static VALUE
2201 sock_s_getnameinfo(argc, argv)
2202 int argc;
2203 VALUE *argv;
2204 {
2205 VALUE sa, af = Qnil, host = Qnil, port = Qnil, flags;
2206 char *hptr, *pptr;
2207 char hbuf[1024], pbuf[1024];
2208 int fl;
2209 struct addrinfo hints, *res = NULL, *r;
2210 int error;
2211 struct sockaddr_storage ss;
2212 struct sockaddr *sap;
2213 char *ep, *ap;
2214
2215 sa = flags = Qnil;
2216 rb_scan_args(argc, argv, "11", &sa, &flags);
2217
2218 fl = 0;
2219 if (!NIL_P(flags)) {
2220 fl = NUM2INT(flags);
2221 }
2222 if (TYPE(sa) == T_STRING) {
2223 if (sizeof(ss) < RSTRING(sa)->len) {
2224 rb_raise(rb_eTypeError, "sockaddr length too big");
2225 }
2226 memcpy(&ss, RSTRING(sa)->ptr, RSTRING(sa)->len);
2227 if (RSTRING(sa)->len != SA_LEN((struct sockaddr*)&ss)) {
2228 rb_raise(rb_eTypeError, "sockaddr size differs - should not happen");
2229 }
2230 sap = (struct sockaddr*)&ss;
2231 }
2232 else if (TYPE(sa) == T_ARRAY) {
2233 MEMZERO(&hints, struct addrinfo, 1);
2234 if (RARRAY(sa)->len == 3) {
2235 af = RARRAY(sa)->ptr[0];
2236 port = RARRAY(sa)->ptr[1];
2237 host = RARRAY(sa)->ptr[2];
2238 }
2239 else if (RARRAY(sa)->len >= 4) {
2240 af = RARRAY(sa)->ptr[0];
2241 port = RARRAY(sa)->ptr[1];
2242 host = RARRAY(sa)->ptr[3];
2243 if (NIL_P(host)) {
2244 host = RARRAY(sa)->ptr[2];
2245 }
2246 else {
2247
2248
2249
2250
2251 hints.ai_flags |= AI_NUMERICHOST;
2252 }
2253 }
2254 else {
2255 rb_raise(rb_eArgError, "array size should be 3 or 4, %d given",
2256 RARRAY(sa)->len);
2257 }
2258
2259 if (NIL_P(host)) {
2260 hptr = NULL;
2261 }
2262 else {
2263 strncpy(hbuf, StringValuePtr(host), sizeof(hbuf));
2264 hbuf[sizeof(hbuf) - 1] = '\0';
2265 hptr = hbuf;
2266 }
2267
2268 if (NIL_P(port)) {
2269 strcpy(pbuf, "0");
2270 pptr = NULL;
2271 }
2272 else if (FIXNUM_P(port)) {
2273 snprintf(pbuf, sizeof(pbuf), "%ld", NUM2INT(port));
2274 pptr = pbuf;
2275 }
2276 else {
2277 strncpy(pbuf, StringValuePtr(port), sizeof(pbuf));
2278 pbuf[sizeof(pbuf) - 1] = '\0';
2279 pptr = pbuf;
2280 }
2281 hints.ai_socktype = (fl & NI_DGRAM) ? SOCK_DGRAM : SOCK_STREAM;
2282
2283 if (NIL_P(af)) {
2284 hints.ai_family = PF_UNSPEC;
2285 }
2286 else if (FIXNUM_P(af)) {
2287 hints.ai_family = FIX2INT(af);
2288 }
2289 else if ((ap = StringValuePtr(af)) != 0) {
2290 if (strcmp(ap, "AF_INET") == 0) {
2291 hints.ai_family = PF_INET;
2292 }
2293 #ifdef INET6
2294 else if (strcmp(ap, "AF_INET6") == 0) {
2295 hints.ai_family = PF_INET6;
2296 }
2297 #endif
2298 }
2299 error = getaddrinfo(hptr, pptr, &hints, &res);
2300 if (error) goto error_exit_addr;
2301 sap = res->ai_addr;
2302 }
2303 else {
2304 rb_raise(rb_eTypeError, "expecting String or Array");
2305 }
2306
2307 error = getnameinfo(sap, SA_LEN(sap), hbuf, sizeof(hbuf),
2308 pbuf, sizeof(pbuf), fl);
2309 if (error) goto error_exit_name;
2310 if (res) {
2311 for (r = res->ai_next; r; r = r->ai_next) {
2312 char hbuf2[1024], pbuf2[1024];
2313
2314 sap = r->ai_addr;
2315 error = getnameinfo(sap, SA_LEN(sap), hbuf2, sizeof(hbuf2),
2316 pbuf2, sizeof(pbuf2), fl);
2317 if (error) goto error_exit_name;
2318 if (strcmp(hbuf, hbuf2) != 0|| strcmp(pbuf, pbuf2) != 0) {
2319 freeaddrinfo(res);
2320 rb_raise(rb_eSocket, "sockaddr resolved to multiple nodename");
2321 }
2322 }
2323 freeaddrinfo(res);
2324 }
2325 return rb_assoc_new(rb_str_new2(hbuf), rb_str_new2(pbuf));
2326
2327 error_exit_addr:
2328 if (res) freeaddrinfo(res);
2329 rb_raise(rb_eSocket, "getaddrinfo: %s", gai_strerror(error));
2330
2331 error_exit_name:
2332 if (res) freeaddrinfo(res);
2333 rb_raise(rb_eSocket, "getnameinfo: %s", gai_strerror(error));
2334 }
2335
2336 static VALUE
2337 sock_s_pack_sockaddr_in(self, port, host)
2338 VALUE self, port, host;
2339 {
2340 struct addrinfo *res = sock_addrinfo(host, port, 0, 0);
2341 VALUE addr = rb_str_new((char*)res->ai_addr, res->ai_addrlen);
2342
2343 freeaddrinfo(res);
2344 OBJ_INFECT(addr, port);
2345 OBJ_INFECT(addr, host);
2346
2347 return addr;
2348 }
2349
2350 static VALUE
2351 sock_s_unpack_sockaddr_in(self, addr)
2352 VALUE self, addr;
2353 {
2354 struct sockaddr_in * sockaddr;
2355 VALUE host;
2356
2357 sockaddr = (struct sockaddr_in*)StringValuePtr(addr);
2358 if (RSTRING(addr)->len != sizeof(struct sockaddr_in)) {
2359 rb_raise(rb_eTypeError, "sockaddr_in size differs - %d required; %d given",
2360 RSTRING(addr)->len, sizeof(struct sockaddr_in));
2361 }
2362 host = mkipaddr(sockaddr);
2363 OBJ_INFECT(host, addr);
2364 return rb_assoc_new(INT2NUM(ntohs(sockaddr->sin_port)), host);
2365 }
2366
2367 #ifdef HAVE_SYS_UN_H
2368 static VALUE
2369 sock_s_pack_sockaddr_un(self, path)
2370 VALUE self, path;
2371 {
2372 struct sockaddr_un sockaddr;
2373 VALUE addr;
2374
2375 MEMZERO(&sockaddr, struct sockaddr_un, 1);
2376 sockaddr.sun_family = AF_UNIX;
2377 strncpy(sockaddr.sun_path, StringValuePtr(path), sizeof(sockaddr.sun_path)-1);
2378 addr = rb_str_new((char*)&sockaddr, sizeof(sockaddr));
2379 OBJ_INFECT(addr, path);
2380
2381 return addr;
2382 }
2383
2384 static VALUE
2385 sock_s_unpack_sockaddr_un(self, addr)
2386 VALUE self, addr;
2387 {
2388 struct sockaddr_un * sockaddr;
2389 VALUE path;
2390
2391 sockaddr = (struct sockaddr_un*)StringValuePtr(addr);
2392 if (RSTRING(addr)->len != sizeof(struct sockaddr_un)) {
2393 rb_raise(rb_eTypeError, "sockaddr_un size differs - %d required; %d given",
2394 RSTRING(addr)->len, sizeof(struct sockaddr_un));
2395 }
2396
2397 path = rb_str_new2(sockaddr->sun_path);
2398 OBJ_INFECT(path, addr);
2399 return path;
2400 }
2401 #endif
2402
2403 static VALUE mConst;
2404
2405 static void
2406 sock_define_const(name, value)
2407 char *name;
2408 int value;
2409 {
2410 rb_define_const(rb_cSocket, name, INT2FIX(value));
2411 rb_define_const(mConst, name, INT2FIX(value));
2412 }
2413
2414 void
2415 Init_socket()
2416 {
2417 rb_eSocket = rb_define_class("SocketError", rb_eStandardError);
2418
2419 rb_cBasicSocket = rb_define_class("BasicSocket", rb_cIO);
2420 rb_undef_method(rb_cBasicSocket, "initialize");
2421
2422 rb_define_singleton_method(rb_cBasicSocket, "do_not_reverse_lookup",
2423 bsock_do_not_rev_lookup, 0);
2424 rb_define_singleton_method(rb_cBasicSocket, "do_not_reverse_lookup=",
2425 bsock_do_not_rev_lookup_set, 1);
2426 rb_define_singleton_method(rb_cBasicSocket, "for_fd", bsock_s_for_fd, 1);
2427
2428 rb_define_method(rb_cBasicSocket, "close_read", bsock_close_read, 0);
2429 rb_define_method(rb_cBasicSocket, "close_write", bsock_close_write, 0);
2430 rb_define_method(rb_cBasicSocket, "shutdown", bsock_shutdown, -1);
2431 rb_define_method(rb_cBasicSocket, "setsockopt", bsock_setsockopt, 3);
2432 rb_define_method(rb_cBasicSocket, "getsockopt", bsock_getsockopt, 2);
2433 rb_define_method(rb_cBasicSocket, "getsockname", bsock_getsockname, 0);
2434 rb_define_method(rb_cBasicSocket, "getpeername", bsock_getpeername, 0);
2435 rb_define_method(rb_cBasicSocket, "send", bsock_send, -1);
2436 rb_define_method(rb_cBasicSocket, "recv", bsock_recv, -1);
2437
2438 rb_cIPSocket = rb_define_class("IPSocket", rb_cBasicSocket);
2439 rb_define_global_const("IPsocket", rb_cIPSocket);
2440 rb_define_method(rb_cIPSocket, "addr", ip_addr, 0);
2441 rb_define_method(rb_cIPSocket, "peeraddr", ip_peeraddr, 0);
2442 rb_define_method(rb_cIPSocket, "recvfrom", ip_recvfrom, -1);
2443 rb_define_singleton_method(rb_cIPSocket, "getaddress", ip_s_getaddress, 1);
2444
2445 rb_cTCPSocket = rb_define_class("TCPSocket", rb_cIPSocket);
2446 rb_define_global_const("TCPsocket", rb_cTCPSocket);
2447 rb_define_singleton_method(rb_cTCPSocket, "gethostbyname", tcp_s_gethostbyname, 1);
2448 rb_define_method(rb_cTCPSocket, "initialize", tcp_init, -1);
2449
2450 #ifdef SOCKS
2451 rb_cSOCKSSocket = rb_define_class("SOCKSSocket", rb_cTCPSocket);
2452 rb_define_global_const("SOCKSsocket", rb_cSOCKSSocket);
2453 rb_define_method(rb_cSOCKSSocket, "initialize", socks_init, 2);
2454 #ifdef SOCKS5
2455 rb_define_method(rb_cSOCKSSocket, "close", socks_s_close, 0);
2456 #endif
2457 #endif
2458
2459 rb_cTCPServer = rb_define_class("TCPServer", rb_cTCPSocket);
2460 rb_define_global_const("TCPserver", rb_cTCPServer);
2461 rb_define_method(rb_cTCPServer, "accept", tcp_accept, 0);
2462 rb_define_method(rb_cTCPServer, "sysaccept", tcp_sysaccept, 0);
2463 rb_define_method(rb_cTCPServer, "initialize", tcp_svr_init, -1);
2464 rb_define_method(rb_cTCPServer, "listen", sock_listen, 1);
2465
2466 rb_cUDPSocket = rb_define_class("UDPSocket", rb_cIPSocket);
2467 rb_define_global_const("UDPsocket", rb_cUDPSocket);
2468 rb_define_method(rb_cUDPSocket, "initialize", udp_init, -1);
2469 rb_define_method(rb_cUDPSocket, "connect", udp_connect, 2);
2470 rb_define_method(rb_cUDPSocket, "bind", udp_bind, 2);
2471 rb_define_method(rb_cUDPSocket, "send", udp_send, -1);
2472
2473 #ifdef HAVE_SYS_UN_H
2474 rb_cUNIXSocket = rb_define_class("UNIXSocket", rb_cBasicSocket);
2475 rb_define_global_const("UNIXsocket", rb_cUNIXSocket);
2476 rb_define_method(rb_cUNIXSocket, "initialize", unix_init, 1);
2477 rb_define_method(rb_cUNIXSocket, "path", unix_path, 0);
2478 rb_define_method(rb_cUNIXSocket, "addr", unix_addr, 0);
2479 rb_define_method(rb_cUNIXSocket, "peeraddr", unix_peeraddr, 0);
2480 rb_define_method(rb_cUNIXSocket, "recvfrom", unix_recvfrom, -1);
2481 rb_define_method(rb_cUNIXSocket, "send_io", unix_send_io, 1);
2482 rb_define_method(rb_cUNIXSocket, "recv_io", unix_recv_io, -1);
2483 rb_define_singleton_method(rb_cUNIXSocket, "socketpair", unix_s_socketpair, -1);
2484 rb_define_singleton_method(rb_cUNIXSocket, "pair", unix_s_socketpair, -1);
2485
2486 rb_cUNIXServer = rb_define_class("UNIXServer", rb_cUNIXSocket);
2487 rb_define_global_const("UNIXserver", rb_cUNIXServer);
2488 rb_define_method(rb_cUNIXServer, "initialize", unix_svr_init, 1);
2489 rb_define_method(rb_cUNIXServer, "accept", unix_accept, 0);
2490 rb_define_method(rb_cUNIXServer, "sysaccept", unix_sysaccept, 0);
2491 rb_define_method(rb_cUNIXServer, "listen", sock_listen, 1);
2492 #endif
2493
2494 rb_cSocket = rb_define_class("Socket", rb_cBasicSocket);
2495
2496 rb_define_method(rb_cSocket, "initialize", sock_init, 3);
2497 rb_define_method(rb_cSocket, "connect", sock_connect, 1);
2498 rb_define_method(rb_cSocket, "bind", sock_bind, 1);
2499 rb_define_method(rb_cSocket, "listen", sock_listen, 1);
2500 rb_define_method(rb_cSocket, "accept", sock_accept, 0);
2501 rb_define_method(rb_cSocket, "sysaccept", sock_sysaccept, 0);
2502
2503 rb_define_method(rb_cSocket, "recvfrom", sock_recvfrom, -1);
2504
2505 rb_define_singleton_method(rb_cSocket, "socketpair", sock_s_socketpair, 3);
2506 rb_define_singleton_method(rb_cSocket, "pair", sock_s_socketpair, 3);
2507 rb_define_singleton_method(rb_cSocket, "gethostname", sock_gethostname, 0);
2508 rb_define_singleton_method(rb_cSocket, "gethostbyname", sock_s_gethostbyname, 1);
2509 rb_define_singleton_method(rb_cSocket, "gethostbyaddr", sock_s_gethostbyaddr, -1);
2510 rb_define_singleton_method(rb_cSocket, "getservbyname", sock_s_getservbyaname, -1);
2511 rb_define_singleton_method(rb_cSocket, "getaddrinfo", sock_s_getaddrinfo, -1);
2512 rb_define_singleton_method(rb_cSocket, "getnameinfo", sock_s_getnameinfo, -1);
2513 rb_define_singleton_method(rb_cSocket, "sockaddr_in", sock_s_pack_sockaddr_in, 2);
2514 rb_define_singleton_method(rb_cSocket, "pack_sockaddr_in", sock_s_pack_sockaddr_in, 2);
2515 rb_define_singleton_method(rb_cSocket, "unpack_sockaddr_in", sock_s_unpack_sockaddr_in, 1);
2516 #ifdef HAVE_SYS_UN_H
2517 rb_define_singleton_method(rb_cSocket, "sockaddr_un", sock_s_pack_sockaddr_un, 1);
2518 rb_define_singleton_method(rb_cSocket, "pack_sockaddr_un", sock_s_pack_sockaddr_un, 1);
2519 rb_define_singleton_method(rb_cSocket, "unpack_sockaddr_un", sock_s_unpack_sockaddr_un, 1);
2520 #endif
2521
2522
2523 mConst = rb_define_module_under(rb_cSocket, "Constants");
2524 sock_define_const("SOCK_STREAM", SOCK_STREAM);
2525 sock_define_const("SOCK_DGRAM", SOCK_DGRAM);
2526 #ifdef SOCK_RAW
2527 sock_define_const("SOCK_RAW", SOCK_RAW);
2528 #endif
2529 #ifdef SOCK_RDM
2530 sock_define_const("SOCK_RDM", SOCK_RDM);
2531 #endif
2532 #ifdef SOCK_SEQPACKET
2533 sock_define_const("SOCK_SEQPACKET", SOCK_SEQPACKET);
2534 #endif
2535 #ifdef SOCK_PACKET
2536 sock_define_const("SOCK_PACKET", SOCK_PACKET);
2537 #endif
2538
2539 sock_define_const("AF_INET", AF_INET);
2540 #ifdef PF_INET
2541 sock_define_const("PF_INET", PF_INET);
2542 #endif
2543 #ifdef AF_UNIX
2544 sock_define_const("AF_UNIX", AF_UNIX);
2545 sock_define_const("PF_UNIX", PF_UNIX);
2546 #endif
2547 #ifdef AF_AX25
2548 sock_define_const("AF_AX25", AF_AX25);
2549 sock_define_const("PF_AX25", PF_AX25);
2550 #endif
2551 #ifdef AF_IPX
2552 sock_define_const("AF_IPX", AF_IPX);
2553 sock_define_const("PF_IPX", PF_IPX);
2554 #endif
2555 #ifdef AF_APPLETALK
2556 sock_define_const("AF_APPLETALK", AF_APPLETALK);
2557 sock_define_const("PF_APPLETALK", PF_APPLETALK);
2558 #endif
2559 #ifdef AF_UNSPEC
2560 sock_define_const("AF_UNSPEC", AF_UNSPEC);
2561 sock_define_const("PF_UNSPEC", PF_UNSPEC);
2562 #endif
2563 #ifdef AF_INET6
2564 sock_define_const("AF_INET6", AF_INET6);
2565 #endif
2566 #ifdef PF_INET6
2567 sock_define_const("PF_INET6", PF_INET6);
2568 #endif
2569
2570 sock_define_const("MSG_OOB", MSG_OOB);
2571 #ifdef MSG_PEEK
2572 sock_define_const("MSG_PEEK", MSG_PEEK);
2573 #endif
2574 #ifdef MSG_DONTROUTE
2575 sock_define_const("MSG_DONTROUTE", MSG_DONTROUTE);
2576 #endif
2577
2578 sock_define_const("SOL_SOCKET", SOL_SOCKET);
2579 #ifdef SOL_IP
2580 sock_define_const("SOL_IP", SOL_IP);
2581 #endif
2582 #ifdef SOL_IPX
2583 sock_define_const("SOL_IPX", SOL_IPX);
2584 #endif
2585 #ifdef SOL_AX25
2586 sock_define_const("SOL_AX25", SOL_AX25);
2587 #endif
2588 #ifdef SOL_ATALK
2589 sock_define_const("SOL_ATALK", SOL_ATALK);
2590 #endif
2591 #ifdef SOL_TCP
2592 sock_define_const("SOL_TCP", SOL_TCP);
2593 #endif
2594 #ifdef SOL_UDP
2595 sock_define_const("SOL_UDP", SOL_UDP);
2596 #endif
2597
2598 #ifdef IPPROTO_IP
2599 sock_define_const("IPPROTO_IP", IPPROTO_IP);
2600 #else
2601 sock_define_const("IPPROTO_IP", 0);
2602 #endif
2603 #ifdef IPPROTO_ICMP
2604 sock_define_const("IPPROTO_ICMP", IPPROTO_ICMP);
2605 #else
2606 sock_define_const("IPPROTO_ICMP", 1);
2607 #endif
2608 #ifdef IPPROTO_IGMP
2609 sock_define_const("IPPROTO_IGMP", IPPROTO_IGMP);
2610 #endif
2611 #ifdef IPPROTO_GGP
2612 sock_define_const("IPPROTO_GGP", IPPROTO_GGP);
2613 #endif
2614 #ifdef IPPROTO_TCP
2615 sock_define_const("IPPROTO_TCP", IPPROTO_TCP);
2616 #else
2617 sock_define_const("IPPROTO_TCP", 6);
2618 #endif
2619 #ifdef IPPROTO_EGP
2620 sock_define_const("IPPROTO_EGP", IPPROTO_EGP);
2621 #endif
2622 #ifdef IPPROTO_PUP
2623 sock_define_const("IPPROTO_PUP", IPPROTO_PUP);
2624 #endif
2625 #ifdef IPPROTO_UDP
2626 sock_define_const("IPPROTO_UDP", IPPROTO_UDP);
2627 #else
2628 sock_define_const("IPPROTO_UDP", 17);
2629 #endif
2630 #ifdef IPPROTO_IDP
2631 sock_define_const("IPPROTO_IDP", IPPROTO_IDP);
2632 #endif
2633 #ifdef IPPROTO_HELLO
2634 sock_define_const("IPPROTO_HELLO", IPPROTO_HELLO);
2635 #endif
2636 #ifdef IPPROTO_ND
2637 sock_define_const("IPPROTO_ND", IPPROTO_ND);
2638 #endif
2639 #ifdef IPPROTO_TP
2640 sock_define_const("IPPROTO_TP", IPPROTO_TP);
2641 #endif
2642 #ifdef IPPROTO_XTP
2643 sock_define_const("IPPROTO_XTP", IPPROTO_XTP);
2644 #endif
2645 #ifdef IPPROTO_EON
2646 sock_define_const("IPPROTO_EON", IPPROTO_EON);
2647 #endif
2648 #ifdef IPPROTO_BIP
2649 sock_define_const("IPPROTO_BIP", IPPROTO_BIP);
2650 #endif
2651
2652 #ifdef IPPROTO_RAW
2653 sock_define_const("IPPROTO_RAW", IPPROTO_RAW);
2654 #else
2655 sock_define_const("IPPROTO_RAW", 255);
2656 #endif
2657 #ifdef IPPROTO_MAX
2658 sock_define_const("IPPROTO_MAX", IPPROTO_MAX);
2659 #endif
2660
2661
2662 #ifdef IPPORT_RESERVED
2663 sock_define_const("IPPORT_RESERVED", IPPORT_RESERVED);
2664 #else
2665 sock_define_const("IPPORT_RESERVED", 1024);
2666 #endif
2667 #ifdef IPPORT_USERRESERVED
2668 sock_define_const("IPPORT_USERRESERVED", IPPORT_USERRESERVED);
2669 #else
2670 sock_define_const("IPPORT_USERRESERVED", 5000);
2671 #endif
2672
2673 #ifdef INADDR_ANY
2674 sock_define_const("INADDR_ANY", INADDR_ANY);
2675 #else
2676 sock_define_const("INADDR_ANY", 0x00000000);
2677 #endif
2678 #ifdef INADDR_BROADCAST
2679 sock_define_const("INADDR_BROADCAST", INADDR_BROADCAST);
2680 #else
2681 sock_define_const("INADDR_BROADCAST", 0xffffffff);
2682 #endif
2683 #ifdef INADDR_LOOPBACK
2684 sock_define_const("INADDR_LOOPBACK", INADDR_LOOPBACK);
2685 #else
2686 sock_define_const("INADDR_LOOPBACK", 0x7F000001);
2687 #endif
2688 #ifdef INADDR_UNSPEC_GROUP
2689 sock_define_const("INADDR_UNSPEC_GROUP", INADDR_UNSPEC_GROUP);
2690 #else
2691 sock_define_const("INADDR_UNSPEC_GROUP", 0xe0000000);
2692 #endif
2693 #ifdef INADDR_ALLHOSTS_GROUP
2694 sock_define_const("INADDR_ALLHOSTS_GROUP", INADDR_ALLHOSTS_GROUP);
2695 #else
2696 sock_define_const("INADDR_ALLHOSTS_GROUP", 0xe0000001);
2697 #endif
2698 #ifdef INADDR_MAX_LOCAL_GROUP
2699 sock_define_const("INADDR_MAX_LOCAL_GROUP", INADDR_MAX_LOCAL_GROUP);
2700 #else
2701 sock_define_const("INADDR_MAX_LOCAL_GROUP", 0xe00000ff);
2702 #endif
2703 #ifdef INADDR_NONE
2704 sock_define_const("INADDR_NONE", INADDR_NONE);
2705 #else
2706 sock_define_const("INADDR_NONE", 0xffffffff);
2707 #endif
2708
2709 #ifdef IP_OPTIONS
2710 sock_define_const("IP_OPTIONS", IP_OPTIONS);
2711 #endif
2712 #ifdef IP_HDRINCL
2713 sock_define_const("IP_HDRINCL", IP_HDRINCL);
2714 #endif
2715 #ifdef IP_TOS
2716 sock_define_const("IP_TOS", IP_TOS);
2717 #endif
2718 #ifdef IP_TTL
2719 sock_define_const("IP_TTL", IP_TTL);
2720 #endif
2721 #ifdef IP_RECVOPTS
2722 sock_define_const("IP_RECVOPTS", IP_RECVOPTS);
2723 #endif
2724 #ifdef IP_RECVRETOPTS
2725 sock_define_const("IP_RECVRETOPTS", IP_RECVRETOPTS);
2726 #endif
2727 #ifdef IP_RECVDSTADDR
2728 sock_define_const("IP_RECVDSTADDR", IP_RECVDSTADDR);
2729 #endif
2730 #ifdef IP_RETOPTS
2731 sock_define_const("IP_RETOPTS", IP_RETOPTS);
2732 #endif
2733 #ifdef IP_MULTICAST_IF
2734 sock_define_const("IP_MULTICAST_IF", IP_MULTICAST_IF);
2735 #endif
2736 #ifdef IP_MULTICAST_TTL
2737 sock_define_const("IP_MULTICAST_TTL", IP_MULTICAST_TTL);
2738 #endif
2739 #ifdef IP_MULTICAST_LOOP
2740 sock_define_const("IP_MULTICAST_LOOP", IP_MULTICAST_LOOP);
2741 #endif
2742 #ifdef IP_ADD_MEMBERSHIP
2743 sock_define_const("IP_ADD_MEMBERSHIP", IP_ADD_MEMBERSHIP);
2744 #endif
2745 #ifdef IP_DROP_MEMBERSHIP
2746 sock_define_const("IP_DROP_MEMBERSHIP", IP_DROP_MEMBERSHIP);
2747 #endif
2748 #ifdef IP_DEFAULT_MULTICAST_TTL
2749 sock_define_const("IP_DEFAULT_MULTICAST_TTL", IP_DEFAULT_MULTICAST_TTL);
2750 #endif
2751 #ifdef IP_DEFAULT_MULTICAST_LOOP
2752 sock_define_const("IP_DEFAULT_MULTICAST_LOOP", IP_DEFAULT_MULTICAST_LOOP);
2753 #endif
2754 #ifdef IP_MAX_MEMBERSHIPS
2755 sock_define_const("IP_MAX_MEMBERSHIPS", IP_MAX_MEMBERSHIPS);
2756 #endif
2757 #ifdef SO_DEBUG
2758 sock_define_const("SO_DEBUG", SO_DEBUG);
2759 #endif
2760 sock_define_const("SO_REUSEADDR", SO_REUSEADDR);
2761 #ifdef SO_TYPE
2762 sock_define_const("SO_TYPE", SO_TYPE);
2763 #endif
2764 #ifdef SO_ERROR
2765 sock_define_const("SO_ERROR", SO_ERROR);
2766 #endif
2767 #ifdef SO_DONTROUTE
2768 sock_define_const("SO_DONTROUTE", SO_DONTROUTE);
2769 #endif
2770 #ifdef SO_BROADCAST
2771 sock_define_const("SO_BROADCAST", SO_BROADCAST);
2772 #endif
2773 #ifdef SO_SNDBUF
2774 sock_define_const("SO_SNDBUF", SO_SNDBUF);
2775 #endif
2776 #ifdef SO_RCVBUF
2777 sock_define_const("SO_RCVBUF", SO_RCVBUF);
2778 #endif
2779 #ifdef SO_KEEPALIVE
2780 sock_define_const("SO_KEEPALIVE", SO_KEEPALIVE);
2781 #endif
2782 #ifdef SO_OOBINLINE
2783 sock_define_const("SO_OOBINLINE", SO_OOBINLINE);
2784 #endif
2785 #ifdef SO_NO_CHECK
2786 sock_define_const("SO_NO_CHECK", SO_NO_CHECK);
2787 #endif
2788 #ifdef SO_PRIORITY
2789 sock_define_const("SO_PRIORITY", SO_PRIORITY);
2790 #endif
2791 #ifdef SO_LINGER
2792 sock_define_const("SO_LINGER", SO_LINGER);
2793 #endif
2794 #ifdef SO_PASSCRED
2795 sock_define_const("SO_PASSCRED", SO_PASSCRED);
2796 #endif
2797 #ifdef SO_PEERCRED
2798 sock_define_const("SO_PEERCRED", SO_PEERCRED);
2799 #endif
2800 #ifdef SO_RCVLOWAT
2801 sock_define_const("SO_RCVLOWAT", SO_RCVLOWAT);
2802 #endif
2803 #ifdef SO_SNDLOWAT
2804 sock_define_const("SO_SNDLOWAT", SO_SNDLOWAT);
2805 #endif
2806 #ifdef SO_RCVTIMEO
2807 sock_define_const("SO_RCVTIMEO", SO_RCVTIMEO);
2808 #endif
2809 #ifdef SO_SNDTIMEO
2810 sock_define_const("SO_SNDTIMEO", SO_SNDTIMEO);
2811 #endif
2812
2813 #ifdef SO_SECURITY_AUTHENTICATION
2814 sock_define_const("SO_SECURITY_AUTHENTICATION", SO_SECURITY_AUTHENTICATION);
2815 #endif
2816 #ifdef SO_SECURITY_ENCRYPTION_TRANSPORT
2817 sock_define_const("SO_SECURITY_ENCRYPTION_TRANSPORT", SO_SECURITY_ENCRYPTION_TRANSPORT);
2818 #endif
2819 #ifdef SO_SECURITY_ENCRYPTION_NETWORK
2820 sock_define_const("SO_SECURITY_ENCRYPTION_NETWORK", SO_SECURITY_ENCRYPTION_NETWORK);
2821 #endif
2822
2823 #ifdef SO_BINDTODEVICE
2824 sock_define_const("SO_BINDTODEVICE", SO_BINDTODEVICE);
2825 #endif
2826 #ifdef SO_ATTACH_FILTER
2827 sock_define_const("SO_ATTACH_FILTER", SO_ATTACH_FILTER);
2828 #endif
2829 #ifdef SO_DETACH_FILTER
2830 sock_define_const("SO_DETACH_FILTER", SO_DETACH_FILTER);
2831 #endif
2832 #ifdef SO_PEERNAME
2833 sock_define_const("SO_PEERNAME", SO_PEERNAME);
2834 #endif
2835 #ifdef SO_TIMESTAMP
2836 sock_define_const("SO_TIMESTAMP", SO_TIMESTAMP);
2837 #endif
2838
2839 #ifdef SOPRI_INTERACTIVE
2840 sock_define_const("SOPRI_INTERACTIVE", SOPRI_INTERACTIVE);
2841 #endif
2842 #ifdef SOPRI_NORMAL
2843 sock_define_const("SOPRI_NORMAL", SOPRI_NORMAL);
2844 #endif
2845 #ifdef SOPRI_BACKGROUND
2846 sock_define_const("SOPRI_BACKGROUND", SOPRI_BACKGROUND);
2847 #endif
2848
2849 #ifdef IPX_TYPE
2850 sock_define_const("IPX_TYPE", IPX_TYPE);
2851 #endif
2852
2853 #ifdef TCP_NODELAY
2854 sock_define_const("TCP_NODELAY", TCP_NODELAY);
2855 #endif
2856 #ifdef TCP_MAXSEG
2857 sock_define_const("TCP_MAXSEG", TCP_MAXSEG);
2858 #endif
2859
2860 #ifdef EAI_ADDRFAMILY
2861 sock_define_const("EAI_ADDRFAMILY", EAI_ADDRFAMILY);
2862 #endif
2863 #ifdef EAI_AGAIN
2864 sock_define_const("EAI_AGAIN", EAI_AGAIN);
2865 #endif
2866 #ifdef EAI_BADFLAGS
2867 sock_define_const("EAI_BADFLAGS", EAI_BADFLAGS);
2868 #endif
2869 #ifdef EAI_FAIL
2870 sock_define_const("EAI_FAIL", EAI_FAIL);
2871 #endif
2872 #ifdef EAI_FAMILY
2873 sock_define_const("EAI_FAMILY", EAI_FAMILY);
2874 #endif
2875 #ifdef EAI_MEMORY
2876 sock_define_const("EAI_MEMORY", EAI_MEMORY);
2877 #endif
2878 #ifdef EAI_NODATA
2879 sock_define_const("EAI_NODATA", EAI_NODATA);
2880 #endif
2881 #ifdef EAI_NONAME
2882 sock_define_const("EAI_NONAME", EAI_NONAME);
2883 #endif
2884 #ifdef EAI_SERVICE
2885 sock_define_const("EAI_SERVICE", EAI_SERVICE);
2886 #endif
2887 #ifdef EAI_SOCKTYPE
2888 sock_define_const("EAI_SOCKTYPE", EAI_SOCKTYPE);
2889 #endif
2890 #ifdef EAI_SYSTEM
2891 sock_define_const("EAI_SYSTEM", EAI_SYSTEM);
2892 #endif
2893 #ifdef EAI_BADHINTS
2894 sock_define_const("EAI_BADHINTS", EAI_BADHINTS);
2895 #endif
2896 #ifdef EAI_PROTOCOL
2897 sock_define_const("EAI_PROTOCOL", EAI_PROTOCOL);
2898 #endif
2899 #ifdef EAI_MAX
2900 sock_define_const("EAI_MAX", EAI_MAX);
2901 #endif
2902 #ifdef AI_PASSIVE
2903 sock_define_const("AI_PASSIVE", AI_PASSIVE);
2904 #endif
2905 #ifdef AI_CANONNAME
2906 sock_define_const("AI_CANONNAME", AI_CANONNAME);
2907 #endif
2908 #ifdef AI_NUMERICHOST
2909 sock_define_const("AI_NUMERICHOST", AI_NUMERICHOST);
2910 #endif
2911 #ifdef AI_MASK
2912 sock_define_const("AI_MASK", AI_MASK);
2913 #endif
2914 #ifdef AI_ALL
2915 sock_define_const("AI_ALL", AI_ALL);
2916 #endif
2917 #ifdef AI_V4MAPPED_CFG
2918 sock_define_const("AI_V4MAPPED_CFG", AI_V4MAPPED_CFG);
2919 #endif
2920 #ifdef AI_ADDRCONFIG
2921 sock_define_const("AI_ADDRCONFIG", AI_ADDRCONFIG);
2922 #endif
2923 #ifdef AI_V4MAPPED
2924 sock_define_const("AI_V4MAPPED", AI_V4MAPPED);
2925 #endif
2926 #ifdef AI_DEFAULT
2927 sock_define_const("AI_DEFAULT", AI_DEFAULT);
2928 #endif
2929 #ifdef NI_MAXHOST
2930 sock_define_const("NI_MAXHOST", NI_MAXHOST);
2931 #endif
2932 #ifdef NI_MAXSERV
2933 sock_define_const("NI_MAXSERV", NI_MAXSERV);
2934 #endif
2935 #ifdef NI_NOFQDN
2936 sock_define_const("NI_NOFQDN", NI_NOFQDN);
2937 #endif
2938 #ifdef NI_NUMERICHOST
2939 sock_define_const("NI_NUMERICHOST", NI_NUMERICHOST);
2940 #endif
2941 #ifdef NI_NAMEREQD
2942 sock_define_const("NI_NAMEREQD", NI_NAMEREQD);
2943 #endif
2944 #ifdef NI_NUMERICSERV
2945 sock_define_const("NI_NUMERICSERV", NI_NUMERICSERV);
2946 #endif
2947 #ifdef NI_DGRAM
2948 sock_define_const("NI_DGRAM", NI_DGRAM);
2949 #endif
2950 }