mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
2000-05-30
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@717 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
869b1efeb4
commit
9a1716fdb2
21 changed files with 245 additions and 185 deletions
|
@ -104,48 +104,18 @@ struct sockaddr_storage {
|
|||
};
|
||||
#endif
|
||||
|
||||
#define LOOKUP_ORDER_UNSPEC 0
|
||||
#define LOOKUP_ORDER_INET 1
|
||||
#define LOOKUP_ORDER_INET6 2
|
||||
|
||||
#if defined(DEFAULT_LOOKUP_ORDER_UNSPEC)
|
||||
# define LOOKUP_ORDER_DEFAULT LOOKUP_ORDER_UNSPEC
|
||||
#elif defined(DEFAULT_LOOKUP_ORDER_INET)
|
||||
# define LOOKUP_ORDER_DEFAULT LOOKUP_ORDER_INET
|
||||
#elif defined(DEFAULT_LOOKUP_ORDER_INET6)
|
||||
# define LOOKUP_ORDER_DEFAULT LOOKUP_ORDER_INET6
|
||||
#endif
|
||||
|
||||
#ifdef INET6
|
||||
#if defined(INET6) && (defined(LOOKUP_ORDER_HACK_INET) || defined(LOOKUP_ORDER_HACK_INET))
|
||||
#define LOOKUP_ORDERS 3
|
||||
int lookup_order_table[LOOKUP_ORDERS][LOOKUP_ORDERS] = {
|
||||
{PF_UNSPEC, PF_UNSPEC, PF_UNSPEC}, /* 0:unspec */
|
||||
{PF_INET, PF_INET6, PF_UNSPEC}, /* 1:inet inet6 */
|
||||
{PF_INET6, PF_INET, PF_UNSPEC} /* 2:inet6 inet */
|
||||
static int lookup_order_table[LOOKUP_ORDERS] = {
|
||||
#if defined(LOOKUP_ORDER_HACK_INET)
|
||||
PF_INET, PF_INET6, PF_UNSPEC,
|
||||
#elif defined(LOOKUP_ORDER_HACK_INET6)
|
||||
PF_INET6, PF_INET, PF_UNSPEC,
|
||||
#else
|
||||
/* should not happen */
|
||||
#endif
|
||||
};
|
||||
|
||||
static int lookup_order = LOOKUP_ORDER_DEFAULT;
|
||||
|
||||
static VALUE
|
||||
lookup_order_get(self)
|
||||
VALUE self;
|
||||
{
|
||||
return INT2FIX(lookup_order);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
lookup_order_set(self, order)
|
||||
VALUE self, order;
|
||||
{
|
||||
int n = NUM2INT(order);
|
||||
|
||||
if (n < 0 || LOOKUP_ORDERS <= n) {
|
||||
rb_raise(rb_eArgError, "invalid value for lookup_order");
|
||||
}
|
||||
lookup_order = n;
|
||||
return order;
|
||||
}
|
||||
|
||||
static int
|
||||
rb_getaddrinfo(nodename, servname, hints, res)
|
||||
char *nodename;
|
||||
|
@ -156,8 +126,12 @@ rb_getaddrinfo(nodename, servname, hints, res)
|
|||
struct addrinfo tmp_hints;
|
||||
int i, af, error;
|
||||
|
||||
if (hints->ai_family != PF_UNSPEC) {
|
||||
return getaddrinfo(nodename, servname, hints, res);
|
||||
}
|
||||
|
||||
for (i = 0; i < LOOKUP_ORDERS; i++) {
|
||||
af = lookup_order_table[lookup_order][i];
|
||||
af = lookup_order_table[i];
|
||||
MEMCPY(&tmp_hints, hints, struct addrinfo, 1);
|
||||
tmp_hints.ai_family = af;
|
||||
error = getaddrinfo(nodename, servname, &tmp_hints, res);
|
||||
|
@ -173,20 +147,7 @@ rb_getaddrinfo(nodename, servname, hints, res)
|
|||
|
||||
return error;
|
||||
}
|
||||
#else
|
||||
static VALUE
|
||||
lookup_order_get(self)
|
||||
VALUE self;
|
||||
{
|
||||
return INT2FIX(LOOKUP_ORDER_DEFAULT);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
lookup_order_set(self, order)
|
||||
VALUE self, order;
|
||||
{
|
||||
return order;
|
||||
}
|
||||
#define getaddrinfo(node,serv,hints,res) rb_getaddrinfo((node),(serv),(hints),(res))
|
||||
#endif
|
||||
|
||||
#ifdef NT
|
||||
|
@ -641,11 +602,7 @@ ip_addrsetup(host, port)
|
|||
MEMZERO(&hints, struct addrinfo, 1);
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
#ifndef INET6
|
||||
error = getaddrinfo(hostp, portp, &hints, &res);
|
||||
#else
|
||||
error = rb_getaddrinfo(hostp, portp, &hints, &res);
|
||||
#endif
|
||||
if (error) {
|
||||
if (hostp && hostp[strlen(hostp)-1] == '\n') {
|
||||
rb_raise(rb_eSocket, "newline at the end of hostname");
|
||||
|
@ -839,11 +796,7 @@ open_inet(class, h, serv, type)
|
|||
if (type == INET_SERVER) {
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
}
|
||||
#ifndef INET6
|
||||
error = getaddrinfo(host, portp, &hints, &res0);
|
||||
#else
|
||||
error = rb_getaddrinfo(host, portp, &hints, &res0);
|
||||
#endif
|
||||
if (error) {
|
||||
rb_raise(rb_eSocket, "%s", gai_strerror(error));
|
||||
}
|
||||
|
@ -1878,11 +1831,9 @@ sock_s_getaddrinfo(argc, argv)
|
|||
if (!NIL_P(family)) {
|
||||
hints.ai_family = NUM2INT(family);
|
||||
}
|
||||
#ifndef INET6
|
||||
else {
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
}
|
||||
#endif
|
||||
if (!NIL_P(socktype)) {
|
||||
hints.ai_socktype = NUM2INT(socktype);
|
||||
}
|
||||
|
@ -1892,16 +1843,7 @@ sock_s_getaddrinfo(argc, argv)
|
|||
if (!NIL_P(flags)) {
|
||||
hints.ai_flags = NUM2INT(flags);
|
||||
}
|
||||
#ifndef INET6
|
||||
error = getaddrinfo(hptr, pptr, &hints, &res);
|
||||
#else
|
||||
if (!NIL_P(family)) {
|
||||
error = getaddrinfo(hptr, pptr, &hints, &res);
|
||||
}
|
||||
else {
|
||||
error = rb_getaddrinfo(hptr, pptr, &hints, &res);
|
||||
}
|
||||
#endif
|
||||
if (error) {
|
||||
rb_raise(rb_eSocket, "%s", gai_strerror(error));
|
||||
}
|
||||
|
@ -1917,13 +1859,14 @@ sock_s_getnameinfo(argc, argv)
|
|||
VALUE *argv;
|
||||
{
|
||||
VALUE sa, af = Qnil, host = Qnil, port = Qnil, flags;
|
||||
static char hbuf[1024], pbuf[1024];
|
||||
char *hptr, *pptr;
|
||||
char hbuf[1024], pbuf[1024];
|
||||
int fl;
|
||||
struct addrinfo hints, *res = NULL;
|
||||
struct addrinfo hints, *res = NULL, *r;
|
||||
int error;
|
||||
struct sockaddr_storage ss;
|
||||
struct sockaddr *sap;
|
||||
char *ep;
|
||||
|
||||
sa = flags = Qnil;
|
||||
rb_scan_args(argc, argv, "11", &sa, &flags);
|
||||
|
@ -1932,7 +1875,6 @@ sock_s_getnameinfo(argc, argv)
|
|||
if (!NIL_P(flags)) {
|
||||
fl = NUM2INT(flags);
|
||||
}
|
||||
|
||||
if (TYPE(sa) == T_STRING) {
|
||||
if (sizeof(ss) < RSTRING(sa)->len) {
|
||||
rb_raise(rb_eTypeError, "sockaddr length too big");
|
||||
|
@ -1944,6 +1886,7 @@ sock_s_getnameinfo(argc, argv)
|
|||
sap = (struct sockaddr *)&ss;
|
||||
}
|
||||
else if (TYPE(sa) == T_ARRAY) {
|
||||
MEMZERO(&hints, struct addrinfo, 1);
|
||||
if (RARRAY(sa)->len == 3) {
|
||||
af = RARRAY(sa)->ptr[0];
|
||||
port = RARRAY(sa)->ptr[1];
|
||||
|
@ -1956,11 +1899,19 @@ sock_s_getnameinfo(argc, argv)
|
|||
if (NIL_P(host)) {
|
||||
host = RARRAY(sa)->ptr[2];
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* 4th element holds numeric form, don't resolve.
|
||||
* see ipaddr().
|
||||
*/
|
||||
hints.ai_flags |= AI_NUMERICHOST;
|
||||
}
|
||||
}
|
||||
else {
|
||||
rb_raise(rb_eArgError, "array size should be 3 or 4, %d given",
|
||||
RARRAY(sa)->len);
|
||||
}
|
||||
/* host */
|
||||
if (NIL_P(host)) {
|
||||
hptr = NULL;
|
||||
}
|
||||
|
@ -1969,6 +1920,7 @@ sock_s_getnameinfo(argc, argv)
|
|||
hbuf[sizeof(hbuf) - 1] = '\0';
|
||||
hptr = hbuf;
|
||||
}
|
||||
/* port */
|
||||
if (NIL_P(port)) {
|
||||
strcpy(pbuf, "0");
|
||||
pptr = NULL;
|
||||
|
@ -1976,15 +1928,21 @@ sock_s_getnameinfo(argc, argv)
|
|||
else if (FIXNUM_P(port)) {
|
||||
snprintf(pbuf, sizeof(pbuf), "%ld", NUM2INT(port));
|
||||
pptr = pbuf;
|
||||
fl |= NI_NUMERICSERV;
|
||||
}
|
||||
else {
|
||||
strncpy(pbuf, STR2CSTR(port), sizeof(pbuf));
|
||||
pbuf[sizeof(pbuf) - 1] = '\0';
|
||||
pptr = pbuf;
|
||||
}
|
||||
MEMZERO(&hints, struct addrinfo, 1);
|
||||
if (strcmp(STR2CSTR(af), "AF_INET") == 0) {
|
||||
hints.ai_socktype = (fl & NI_DGRAM) ? SOCK_DGRAM : SOCK_STREAM;
|
||||
/* af */
|
||||
if (NIL_P(af)) {
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
}
|
||||
else if (FIXNUM_P(af)) {
|
||||
hints.ai_family = FIX2INT(af);
|
||||
}
|
||||
else if (strcmp(STR2CSTR(af), "AF_INET") == 0) {
|
||||
hints.ai_family = PF_INET;
|
||||
}
|
||||
#ifdef INET6
|
||||
|
@ -1992,13 +1950,8 @@ sock_s_getnameinfo(argc, argv)
|
|||
hints.ai_family = PF_INET6;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
}
|
||||
error = getaddrinfo(hptr, pptr, &hints, &res);
|
||||
if (error) {
|
||||
rb_raise(rb_eSocket, "%s", gai_strerror(error));
|
||||
}
|
||||
if (error) goto error_exit;
|
||||
sap = res->ai_addr;
|
||||
}
|
||||
else {
|
||||
|
@ -2007,13 +1960,25 @@ sock_s_getnameinfo(argc, argv)
|
|||
|
||||
error = getnameinfo(sap, SA_LEN(sap), hbuf, sizeof(hbuf),
|
||||
pbuf, sizeof(pbuf), fl);
|
||||
if (error) {
|
||||
rb_raise(rb_eSocket, "%s", gai_strerror(error));
|
||||
}
|
||||
if (res)
|
||||
freeaddrinfo(res);
|
||||
if (error) goto error_exit;
|
||||
for (r = res->ai_next; r; r = r->ai_next) {
|
||||
char hbuf2[1024], pbuf2[1024];
|
||||
|
||||
sap = r->ai_addr;
|
||||
error = getnameinfo(sap, SA_LEN(sap), hbuf2, sizeof(hbuf2),
|
||||
pbuf2, sizeof(pbuf2), fl);
|
||||
if (error) goto error_exit;
|
||||
if (strcmp(hbuf, hbuf2) != 0|| strcmp(pbuf, pbuf2) != 0) {
|
||||
freeaddrinfo(res);
|
||||
rb_raise(rb_eSocket, "sockaddr resolved to multiple nodename");
|
||||
}
|
||||
}
|
||||
freeaddrinfo(res);
|
||||
return rb_assoc_new(rb_tainted_str_new2(hbuf), rb_tainted_str_new2(pbuf));
|
||||
|
||||
error_exit:
|
||||
if (res) freeaddrinfo(res);
|
||||
rb_raise(rb_eSocket, "%s", gai_strerror(error));
|
||||
}
|
||||
|
||||
static VALUE mConst;
|
||||
|
@ -2175,12 +2140,6 @@ Init_socket()
|
|||
sock_define_const("PF_INET6", PF_INET6);
|
||||
#endif
|
||||
|
||||
sock_define_const("LOOKUP_INET", LOOKUP_ORDER_INET);
|
||||
sock_define_const("LOOKUP_INET6", LOOKUP_ORDER_INET6);
|
||||
sock_define_const("LOOKUP_UNSPEC", LOOKUP_ORDER_UNSPEC);
|
||||
rb_define_singleton_method(rb_cBasicSocket, "lookup_order", lookup_order_get, 0);
|
||||
rb_define_singleton_method(rb_cBasicSocket, "lookup_order=", lookup_order_set, 1);
|
||||
|
||||
sock_define_const("MSG_OOB", MSG_OOB);
|
||||
#ifdef MSG_PEEK
|
||||
sock_define_const("MSG_PEEK", MSG_PEEK);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue