diff options
Diffstat (limited to 'ruby_2_2/ext/socket/ipsocket.c')
-rw-r--r-- | ruby_2_2/ext/socket/ipsocket.c | 338 |
1 files changed, 0 insertions, 338 deletions
diff --git a/ruby_2_2/ext/socket/ipsocket.c b/ruby_2_2/ext/socket/ipsocket.c deleted file mode 100644 index 16a83734bb..0000000000 --- a/ruby_2_2/ext/socket/ipsocket.c +++ /dev/null @@ -1,338 +0,0 @@ -/************************************************ - - ipsocket.c - - - created at: Thu Mar 31 12:21:29 JST 1994 - - Copyright (C) 1993-2007 Yukihiro Matsumoto - -************************************************/ - -#include "rubysocket.h" - -struct inetsock_arg -{ - VALUE sock; - struct { - VALUE host, serv; - struct rb_addrinfo *res; - } remote, local; - int type; - int fd; -}; - -static VALUE -inetsock_cleanup(struct inetsock_arg *arg) -{ - if (arg->remote.res) { - rb_freeaddrinfo(arg->remote.res); - arg->remote.res = 0; - } - if (arg->local.res) { - rb_freeaddrinfo(arg->local.res); - arg->local.res = 0; - } - if (arg->fd >= 0) { - close(arg->fd); - } - return Qnil; -} - -static VALUE -init_inetsock_internal(struct inetsock_arg *arg) -{ - int error = 0; - int type = arg->type; - struct addrinfo *res, *lres; - int fd, status = 0, local = 0; - const char *syscall = 0; - - arg->remote.res = rsock_addrinfo(arg->remote.host, arg->remote.serv, SOCK_STREAM, - (type == INET_SERVER) ? AI_PASSIVE : 0); - /* - * Maybe also accept a local address - */ - - if (type != INET_SERVER && (!NIL_P(arg->local.host) || !NIL_P(arg->local.serv))) { - arg->local.res = rsock_addrinfo(arg->local.host, arg->local.serv, SOCK_STREAM, 0); - } - - arg->fd = fd = -1; - for (res = arg->remote.res->ai; res; res = res->ai_next) { -#if !defined(INET6) && defined(AF_INET6) - if (res->ai_family == AF_INET6) - continue; -#endif - lres = NULL; - if (arg->local.res) { - for (lres = arg->local.res->ai; lres; lres = lres->ai_next) { - if (lres->ai_family == res->ai_family) - break; - } - if (!lres) { - if (res->ai_next || status < 0) - continue; - /* Use a different family local address if no choice, this - * will cause EAFNOSUPPORT. */ - lres = arg->local.res->ai; - } - } - status = rsock_socket(res->ai_family,res->ai_socktype,res->ai_protocol); - syscall = "socket(2)"; - fd = status; - if (fd < 0) { - error = errno; - continue; - } - arg->fd = fd; - if (type == INET_SERVER) { -#if !defined(_WIN32) && !defined(__CYGWIN__) - status = 1; - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, - (char*)&status, (socklen_t)sizeof(status)); -#endif - status = bind(fd, res->ai_addr, res->ai_addrlen); - syscall = "bind(2)"; - } - else { - if (lres) { - status = bind(fd, lres->ai_addr, lres->ai_addrlen); - local = status; - syscall = "bind(2)"; - } - - if (status >= 0) { - status = rsock_connect(fd, res->ai_addr, res->ai_addrlen, - (type == INET_SOCKS)); - syscall = "connect(2)"; - } - } - - if (status < 0) { - error = errno; - close(fd); - arg->fd = fd = -1; - continue; - } else - break; - } - if (status < 0) { - VALUE host, port; - - if (local < 0) { - host = arg->local.host; - port = arg->local.serv; - } else { - host = arg->remote.host; - port = arg->remote.serv; - } - - rsock_syserr_fail_host_port(error, syscall, host, port); - } - - arg->fd = -1; - - if (type == INET_SERVER) { - status = listen(fd, SOMAXCONN); - if (status < 0) { - error = errno; - close(fd); - rb_syserr_fail(error, "listen(2)"); - } - } - - /* create new instance */ - return rsock_init_sock(arg->sock, fd); -} - -VALUE -rsock_init_inetsock(VALUE sock, VALUE remote_host, VALUE remote_serv, - VALUE local_host, VALUE local_serv, int type) -{ - struct inetsock_arg arg; - arg.sock = sock; - arg.remote.host = remote_host; - arg.remote.serv = remote_serv; - arg.remote.res = 0; - arg.local.host = local_host; - arg.local.serv = local_serv; - arg.local.res = 0; - arg.type = type; - arg.fd = -1; - return rb_ensure(init_inetsock_internal, (VALUE)&arg, - inetsock_cleanup, (VALUE)&arg); -} - -static ID id_numeric, id_hostname; - -int -rsock_revlookup_flag(VALUE revlookup, int *norevlookup) -{ -#define return_norevlookup(x) {*norevlookup = (x); return 1;} - ID id; - - switch (revlookup) { - case Qtrue: return_norevlookup(0); - case Qfalse: return_norevlookup(1); - case Qnil: break; - default: - Check_Type(revlookup, T_SYMBOL); - id = SYM2ID(revlookup); - if (id == id_numeric) return_norevlookup(1); - if (id == id_hostname) return_norevlookup(0); - rb_raise(rb_eArgError, "invalid reverse_lookup flag: :%s", rb_id2name(id)); - } - return 0; -#undef return_norevlookup -} - -/* - * call-seq: - * ipsocket.addr([reverse_lookup]) => [address_family, port, hostname, numeric_address] - * - * Returns the local address as an array which contains - * address_family, port, hostname and numeric_address. - * - * If +reverse_lookup+ is +true+ or +:hostname+, - * hostname is obtained from numeric_address using reverse lookup. - * Or if it is +false+, or +:numeric+, - * hostname is same as numeric_address. - * Or if it is +nil+ or ommitted, obeys to +ipsocket.do_not_reverse_lookup+. - * See +Socket.getaddrinfo+ also. - * - * TCPSocket.open("www.ruby-lang.org", 80) {|sock| - * p sock.addr #=> ["AF_INET", 49429, "hal", "192.168.0.128"] - * p sock.addr(true) #=> ["AF_INET", 49429, "hal", "192.168.0.128"] - * p sock.addr(false) #=> ["AF_INET", 49429, "192.168.0.128", "192.168.0.128"] - * p sock.addr(:hostname) #=> ["AF_INET", 49429, "hal", "192.168.0.128"] - * p sock.addr(:numeric) #=> ["AF_INET", 49429, "192.168.0.128", "192.168.0.128"] - * } - * - */ -static VALUE -ip_addr(int argc, VALUE *argv, VALUE sock) -{ - rb_io_t *fptr; - union_sockaddr addr; - socklen_t len = (socklen_t)sizeof addr; - int norevlookup; - - GetOpenFile(sock, fptr); - - if (argc < 1 || !rsock_revlookup_flag(argv[0], &norevlookup)) - norevlookup = fptr->mode & FMODE_NOREVLOOKUP; - if (getsockname(fptr->fd, &addr.addr, &len) < 0) - rb_sys_fail("getsockname(2)"); - return rsock_ipaddr(&addr.addr, len, norevlookup); -} - -/* - * call-seq: - * ipsocket.peeraddr([reverse_lookup]) => [address_family, port, hostname, numeric_address] - * - * Returns the remote address as an array which contains - * address_family, port, hostname and numeric_address. - * It is defined for connection oriented socket such as TCPSocket. - * - * If +reverse_lookup+ is +true+ or +:hostname+, - * hostname is obtained from numeric_address using reverse lookup. - * Or if it is +false+, or +:numeric+, - * hostname is same as numeric_address. - * Or if it is +nil+ or ommitted, obeys to +ipsocket.do_not_reverse_lookup+. - * See +Socket.getaddrinfo+ also. - * - * TCPSocket.open("www.ruby-lang.org", 80) {|sock| - * p sock.peeraddr #=> ["AF_INET", 80, "carbon.ruby-lang.org", "221.186.184.68"] - * p sock.peeraddr(true) #=> ["AF_INET", 80, "carbon.ruby-lang.org", "221.186.184.68"] - * p sock.peeraddr(false) #=> ["AF_INET", 80, "221.186.184.68", "221.186.184.68"] - * p sock.peeraddr(:hostname) #=> ["AF_INET", 80, "carbon.ruby-lang.org", "221.186.184.68"] - * p sock.peeraddr(:numeric) #=> ["AF_INET", 80, "221.186.184.68", "221.186.184.68"] - * } - * - */ -static VALUE -ip_peeraddr(int argc, VALUE *argv, VALUE sock) -{ - rb_io_t *fptr; - union_sockaddr addr; - socklen_t len = (socklen_t)sizeof addr; - int norevlookup; - - GetOpenFile(sock, fptr); - - if (argc < 1 || !rsock_revlookup_flag(argv[0], &norevlookup)) - norevlookup = fptr->mode & FMODE_NOREVLOOKUP; - if (getpeername(fptr->fd, &addr.addr, &len) < 0) - rb_sys_fail("getpeername(2)"); - return rsock_ipaddr(&addr.addr, len, norevlookup); -} - -/* - * call-seq: - * ipsocket.recvfrom(maxlen) => [mesg, ipaddr] - * ipsocket.recvfrom(maxlen, flags) => [mesg, ipaddr] - * - * Receives a message and return the message as a string and - * an address which the message come from. - * - * _maxlen_ is the maximum number of bytes to receive. - * - * _flags_ should be a bitwise OR of Socket::MSG_* constants. - * - * ipaddr is same as IPSocket#{peeraddr,addr}. - * - * u1 = UDPSocket.new - * u1.bind("127.0.0.1", 4913) - * u2 = UDPSocket.new - * u2.send "uuuu", 0, "127.0.0.1", 4913 - * p u1.recvfrom(10) #=> ["uuuu", ["AF_INET", 33230, "localhost", "127.0.0.1"]] - * - */ -static VALUE -ip_recvfrom(int argc, VALUE *argv, VALUE sock) -{ - return rsock_s_recvfrom(sock, argc, argv, RECV_IP); -} - -/* - * call-seq: - * IPSocket.getaddress(host) => ipaddress - * - * Lookups the IP address of _host_. - * - * IPSocket.getaddress("localhost") #=> "127.0.0.1" - * IPSocket.getaddress("ip6-localhost") #=> "::1" - * - */ -static VALUE -ip_s_getaddress(VALUE obj, VALUE host) -{ - union_sockaddr addr; - struct rb_addrinfo *res = rsock_addrinfo(host, Qnil, SOCK_STREAM, 0); - socklen_t len = res->ai->ai_addrlen; - - /* just take the first one */ - memcpy(&addr, res->ai->ai_addr, len); - rb_freeaddrinfo(res); - - return rsock_make_ipaddr(&addr.addr, len); -} - -void -rsock_init_ipsocket(void) -{ - /* - * Document-class: IPSocket < BasicSocket - * - * IPSocket is the super class of TCPSocket and UDPSocket. - */ - rb_cIPSocket = rb_define_class("IPSocket", rb_cBasicSocket); - rb_define_method(rb_cIPSocket, "addr", ip_addr, -1); - rb_define_method(rb_cIPSocket, "peeraddr", ip_peeraddr, -1); - rb_define_method(rb_cIPSocket, "recvfrom", ip_recvfrom, -1); - rb_define_singleton_method(rb_cIPSocket, "getaddress", ip_s_getaddress, 1); - rb_undef_method(rb_cIPSocket, "getpeereid"); - - id_numeric = rb_intern_const("numeric"); - id_hostname = rb_intern_const("hostname"); -} |