* ext/socket/raddrinfo.c (addrinfo_mdump): new method.
(addrinfo_mload): new method. (Init_addrinfo): define the method above. * ext/socket/constants.c (constant_arg): str_to_int's first argument constified. * ext/socket/mkconstants.rb (gen_name_to_int_decl): generated function's first argument constified. (gen_name_to_int_func_in_guard): ditto. (ipproto_to_int): generated. * ext/socket/rubysocket.h (IS_IP_FAMILY): moved from raddrinfo.c. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@21643 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
75e0fde36b
commit
86aa5043d8
16
ChangeLog
16
ChangeLog
@ -1,3 +1,19 @@
|
|||||||
|
Sun Jan 18 03:05:20 2009 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* ext/socket/raddrinfo.c (addrinfo_mdump): new method.
|
||||||
|
(addrinfo_mload): new method.
|
||||||
|
(Init_addrinfo): define the method above.
|
||||||
|
|
||||||
|
* ext/socket/constants.c (constant_arg): str_to_int's first argument
|
||||||
|
constified.
|
||||||
|
|
||||||
|
* ext/socket/mkconstants.rb (gen_name_to_int_decl): generated
|
||||||
|
function's first argument constified.
|
||||||
|
(gen_name_to_int_func_in_guard): ditto.
|
||||||
|
(ipproto_to_int): generated.
|
||||||
|
|
||||||
|
* ext/socket/rubysocket.h (IS_IP_FAMILY): moved from raddrinfo.c.
|
||||||
|
|
||||||
Sun Jan 18 01:37:50 2009 Tanaka Akira <akr@fsij.org>
|
Sun Jan 18 01:37:50 2009 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
* ext/socket/socket.c (sock_s_getnameinfo): accept AddrInfo object.
|
* ext/socket/socket.c (sock_s_getnameinfo): accept AddrInfo object.
|
||||||
|
@ -19,7 +19,7 @@ static void sock_define_uconst(const char *name, unsigned int value, VALUE mCons
|
|||||||
#undef sock_define_uconst
|
#undef sock_define_uconst
|
||||||
|
|
||||||
static int
|
static int
|
||||||
constant_arg(VALUE arg, int (*str_to_int)(char*, int, int*), const char *errmsg)
|
constant_arg(VALUE arg, int (*str_to_int)(const char*, int, int*), const char *errmsg)
|
||||||
{
|
{
|
||||||
VALUE tmp;
|
VALUE tmp;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
@ -140,16 +140,16 @@ end
|
|||||||
ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_name_to_int_decl(funcname, pat, prefix_optional, guard=nil)")
|
ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_name_to_int_decl(funcname, pat, prefix_optional, guard=nil)")
|
||||||
%if guard
|
%if guard
|
||||||
#ifdef <%=guard%>
|
#ifdef <%=guard%>
|
||||||
int <%=funcname%>(char *str, int len, int *valp);
|
int <%=funcname%>(const char *str, int len, int *valp);
|
||||||
#endif
|
#endif
|
||||||
%else
|
%else
|
||||||
int <%=funcname%>(char *str, int len, int *valp);
|
int <%=funcname%>(const char *str, int len, int *valp);
|
||||||
%end
|
%end
|
||||||
EOS
|
EOS
|
||||||
|
|
||||||
ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_name_to_int_func_in_guard(funcname, pat, prefix_optional, guard=nil)")
|
ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_name_to_int_func_in_guard(funcname, pat, prefix_optional, guard=nil)")
|
||||||
int
|
int
|
||||||
<%=funcname%>(char *str, int len, int *valp)
|
<%=funcname%>(const char *str, int len, int *valp)
|
||||||
{
|
{
|
||||||
switch (len) {
|
switch (len) {
|
||||||
% each_names_with_len(pat, prefix_optional) {|pairs, len|
|
% each_names_with_len(pat, prefix_optional) {|pairs, len|
|
||||||
@ -241,6 +241,7 @@ end
|
|||||||
|
|
||||||
def_name_to_int("family_to_int", /\A(AF_|PF_)/, "AF_")
|
def_name_to_int("family_to_int", /\A(AF_|PF_)/, "AF_")
|
||||||
def_name_to_int("socktype_to_int", /\ASOCK_/, "SOCK_")
|
def_name_to_int("socktype_to_int", /\ASOCK_/, "SOCK_")
|
||||||
|
def_name_to_int("ipproto_to_int", /\AIPPROTO_/, "IPPROTO_")
|
||||||
def_name_to_int("level_to_int", /\A(SOL_SOCKET\z|IPPROTO_)/, /\A(SOL_|IPPROTO_)/)
|
def_name_to_int("level_to_int", /\A(SOL_SOCKET\z|IPPROTO_)/, /\A(SOL_|IPPROTO_)/)
|
||||||
def_name_to_int("so_optname_to_int", /\ASO_/, "SO_")
|
def_name_to_int("so_optname_to_int", /\ASO_/, "SO_")
|
||||||
def_name_to_int("ip_optname_to_int", /\AIP_/, "IP_")
|
def_name_to_int("ip_optname_to_int", /\AIP_/, "IP_")
|
||||||
|
@ -1081,6 +1081,196 @@ addrinfo_inspect(VALUE self)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* :nodoc: */
|
||||||
|
static VALUE
|
||||||
|
addrinfo_mdump(VALUE self)
|
||||||
|
{
|
||||||
|
rb_addrinfo_t *rai = get_addrinfo(self);
|
||||||
|
VALUE sockaddr, afamily, pfamily, socktype, protocol, canonname, inspectname;
|
||||||
|
int afamily_int = ai_get_afamily(rai);
|
||||||
|
ID id;
|
||||||
|
|
||||||
|
id = intern_protocol_family(rai->pfamily);
|
||||||
|
if (id == 0)
|
||||||
|
rb_raise(rb_eSocket, "unknown protocol family: %d", rai->pfamily);
|
||||||
|
pfamily = ID2SYM(id);
|
||||||
|
|
||||||
|
if (rai->socktype == 0)
|
||||||
|
socktype = INT2FIX(0);
|
||||||
|
else {
|
||||||
|
id = intern_socktype(rai->socktype);
|
||||||
|
if (id == 0)
|
||||||
|
rb_raise(rb_eSocket, "unknown socktype: %d", rai->socktype);
|
||||||
|
socktype = ID2SYM(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rai->protocol == 0)
|
||||||
|
protocol = INT2FIX(0);
|
||||||
|
else if (IS_IP_FAMILY(afamily_int)) {
|
||||||
|
id = intern_ipproto(rai->protocol);
|
||||||
|
if (id == 0)
|
||||||
|
rb_raise(rb_eSocket, "unknown IP protocol: %d", rai->protocol);
|
||||||
|
protocol = ID2SYM(id);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rb_raise(rb_eSocket, "unknown protocol: %d", rai->protocol);
|
||||||
|
}
|
||||||
|
|
||||||
|
canonname = rai->canonname;
|
||||||
|
|
||||||
|
inspectname = rai->inspectname;
|
||||||
|
|
||||||
|
id = intern_family(afamily_int);
|
||||||
|
if (id == 0)
|
||||||
|
rb_raise(rb_eSocket, "unknown address family: %d", afamily_int);
|
||||||
|
afamily = ID2SYM(id);
|
||||||
|
|
||||||
|
switch(afamily_int) {
|
||||||
|
case AF_UNIX:
|
||||||
|
{
|
||||||
|
struct sockaddr_un *su = (struct sockaddr_un *)&rai->addr;
|
||||||
|
char *s, *e;
|
||||||
|
s = su->sun_path;
|
||||||
|
e = (char*)s + sizeof(su->sun_path);
|
||||||
|
while (s < e && *(e-1) == '\0')
|
||||||
|
e--;
|
||||||
|
sockaddr = rb_str_new(s, e-s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
|
||||||
|
int error;
|
||||||
|
error = getnameinfo((struct sockaddr *)&rai->addr, rai->sockaddr_len,
|
||||||
|
hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),
|
||||||
|
NI_NUMERICHOST|NI_NUMERICSERV);
|
||||||
|
if (error) {
|
||||||
|
raise_socket_error("getnameinfo", error);
|
||||||
|
}
|
||||||
|
sockaddr = rb_assoc_new(rb_str_new_cstr(hbuf), rb_str_new_cstr(pbuf));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rb_ary_new3(7, afamily, sockaddr, pfamily, socktype, protocol, canonname, inspectname);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* :nodoc: */
|
||||||
|
static VALUE
|
||||||
|
addrinfo_mload(VALUE self, VALUE ary)
|
||||||
|
{
|
||||||
|
VALUE v;
|
||||||
|
VALUE canonname, inspectname;
|
||||||
|
int afamily, pfamily, socktype, protocol;
|
||||||
|
struct sockaddr_storage ss;
|
||||||
|
size_t len;
|
||||||
|
const char *str;
|
||||||
|
rb_addrinfo_t *rai;
|
||||||
|
|
||||||
|
if (check_addrinfo(self))
|
||||||
|
rb_raise(rb_eTypeError, "already initialized socket address");
|
||||||
|
|
||||||
|
ary = rb_convert_type(ary, T_ARRAY, "Array", "to_ary");
|
||||||
|
|
||||||
|
v = rb_ary_entry(ary, 0);
|
||||||
|
if (!SYMBOL_P(v))
|
||||||
|
rb_raise(rb_eTypeError, "symbol expected for address family");
|
||||||
|
str = rb_id2name(SYM2ID(v));
|
||||||
|
if (family_to_int(str, strlen(str), &afamily) == -1)
|
||||||
|
rb_raise(rb_eTypeError, "unexpected address family");
|
||||||
|
|
||||||
|
v = rb_ary_entry(ary, 2);
|
||||||
|
if (!SYMBOL_P(v))
|
||||||
|
rb_raise(rb_eTypeError, "symbol expected for protocol family");
|
||||||
|
str = rb_id2name(SYM2ID(v));
|
||||||
|
if (family_to_int(str, strlen(str), &pfamily) == -1)
|
||||||
|
rb_raise(rb_eTypeError, "unexpected protocol family");
|
||||||
|
|
||||||
|
v = rb_ary_entry(ary, 3);
|
||||||
|
if (v == INT2FIX(0))
|
||||||
|
socktype = 0;
|
||||||
|
else {
|
||||||
|
if (!SYMBOL_P(v))
|
||||||
|
rb_raise(rb_eTypeError, "symbol expected for socktype");
|
||||||
|
str = rb_id2name(SYM2ID(v));
|
||||||
|
if (socktype_to_int(str, strlen(str), &socktype) == -1)
|
||||||
|
rb_raise(rb_eTypeError, "unexpected socktype");
|
||||||
|
}
|
||||||
|
|
||||||
|
v = rb_ary_entry(ary, 4);
|
||||||
|
if (v == INT2FIX(0))
|
||||||
|
protocol = 0;
|
||||||
|
else {
|
||||||
|
if (!SYMBOL_P(v))
|
||||||
|
rb_raise(rb_eTypeError, "symbol expected for protocol");
|
||||||
|
if (IS_IP_FAMILY(afamily)) {
|
||||||
|
str = rb_id2name(SYM2ID(v));
|
||||||
|
if (ipproto_to_int(str, strlen(str), &protocol) == -1)
|
||||||
|
rb_raise(rb_eTypeError, "unexpected protocol");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rb_raise(rb_eTypeError, "unexpected protocol");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
v = rb_ary_entry(ary, 5);
|
||||||
|
if (NIL_P(v))
|
||||||
|
canonname = Qnil;
|
||||||
|
else {
|
||||||
|
StringValue(v);
|
||||||
|
canonname = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
v = rb_ary_entry(ary, 6);
|
||||||
|
if (NIL_P(v))
|
||||||
|
inspectname = Qnil;
|
||||||
|
else {
|
||||||
|
StringValue(v);
|
||||||
|
inspectname = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
v = rb_ary_entry(ary, 1);
|
||||||
|
switch(afamily) {
|
||||||
|
case AF_UNIX:
|
||||||
|
{
|
||||||
|
struct sockaddr_un *su = (struct sockaddr_un *)&ss;
|
||||||
|
memset(su, 0, sizeof(*su));
|
||||||
|
su->sun_family = AF_UNIX;
|
||||||
|
|
||||||
|
StringValue(v);
|
||||||
|
if (sizeof(su->sun_path) <= RSTRING_LEN(v))
|
||||||
|
rb_raise(rb_eSocket, "too long AF_UNIX path");
|
||||||
|
memcpy(su->sun_path, RSTRING_PTR(v), RSTRING_LEN(v));
|
||||||
|
len = sizeof(*su);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
VALUE pair = rb_convert_type(v, T_ARRAY, "Array", "to_ary");
|
||||||
|
struct addrinfo *res;
|
||||||
|
int flags = AI_NUMERICHOST;
|
||||||
|
#ifdef AI_NUMERICSERV
|
||||||
|
flags |= AI_NUMERICSERV;
|
||||||
|
#endif
|
||||||
|
res = call_getaddrinfo(rb_ary_entry(pair, 0), rb_ary_entry(pair, 1),
|
||||||
|
INT2NUM(pfamily), INT2NUM(socktype), INT2NUM(protocol),
|
||||||
|
INT2NUM(flags), 1);
|
||||||
|
|
||||||
|
len = res->ai_addrlen;
|
||||||
|
memcpy(&ss, res->ai_addr, res->ai_addrlen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DATA_PTR(self) = rai = alloc_addrinfo();
|
||||||
|
init_addrinfo(rai, (struct sockaddr *)&ss, len,
|
||||||
|
pfamily, socktype, protocol,
|
||||||
|
canonname, inspectname);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* addrinfo.afamily => integer
|
* addrinfo.afamily => integer
|
||||||
@ -1187,12 +1377,6 @@ addrinfo_canonname(VALUE self)
|
|||||||
return rai->canonname;
|
return rai->canonname;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef AF_INET6
|
|
||||||
# define IS_IP_FAMILY(af) ((af) == AF_INET || (af) == AF_INET6)
|
|
||||||
#else
|
|
||||||
# define IS_IP_FAMILY(af) ((af) == AF_INET)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* addrinfo.ip? => true or false
|
* addrinfo.ip? => true or false
|
||||||
@ -1603,4 +1787,7 @@ Init_addrinfo(void)
|
|||||||
rb_define_method(rb_cAddrInfo, "to_sockaddr", addrinfo_to_sockaddr, 0);
|
rb_define_method(rb_cAddrInfo, "to_sockaddr", addrinfo_to_sockaddr, 0);
|
||||||
|
|
||||||
rb_define_method(rb_cAddrInfo, "getnameinfo", addrinfo_getnameinfo, -1);
|
rb_define_method(rb_cAddrInfo, "getnameinfo", addrinfo_getnameinfo, -1);
|
||||||
|
|
||||||
|
rb_define_method(rb_cAddrInfo, "marshal_dump", addrinfo_mdump, 0);
|
||||||
|
rb_define_method(rb_cAddrInfo, "marshal_load", addrinfo_mload, 1);
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,12 @@
|
|||||||
# define NI_MAXSERV 32
|
# define NI_MAXSERV 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef AF_INET6
|
||||||
|
# define IS_IP_FAMILY(af) ((af) == AF_INET || (af) == AF_INET6)
|
||||||
|
#else
|
||||||
|
# define IS_IP_FAMILY(af) ((af) == AF_INET)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_SOCKADDR_STORAGE
|
#ifndef HAVE_SOCKADDR_STORAGE
|
||||||
/*
|
/*
|
||||||
* RFC 2553: protocol-independent placeholder for socket addresses
|
* RFC 2553: protocol-independent placeholder for socket addresses
|
||||||
|
@ -274,6 +274,17 @@ class TestSocketAddrInfo < Test::Unit::TestCase
|
|||||||
s2.close if s2 && !s2.closed?
|
s2.close if s2 && !s2.closed?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_marshal
|
||||||
|
ai1 = AddrInfo.tcp("127.0.0.1", 80)
|
||||||
|
ai2 = Marshal.load(Marshal.dump(ai1))
|
||||||
|
assert_equal(ai1.afamily, ai2.afamily)
|
||||||
|
assert_equal(ai1.ip_unpack, ai2.ip_unpack)
|
||||||
|
assert_equal(ai1.pfamily, ai2.pfamily)
|
||||||
|
assert_equal(ai1.socktype, ai2.socktype)
|
||||||
|
assert_equal(ai1.protocol, ai2.protocol)
|
||||||
|
assert_equal(ai1.canonname, ai2.canonname)
|
||||||
|
end
|
||||||
|
|
||||||
if Socket.const_defined?("AF_INET6")
|
if Socket.const_defined?("AF_INET6")
|
||||||
|
|
||||||
def test_addrinfo_new_inet6
|
def test_addrinfo_new_inet6
|
||||||
@ -290,6 +301,17 @@ class TestSocketAddrInfo < Test::Unit::TestCase
|
|||||||
assert_equal(["::1", 80], ai.ip_unpack)
|
assert_equal(["::1", 80], ai.ip_unpack)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_marshal_inet6
|
||||||
|
ai1 = AddrInfo.tcp("::1", 80)
|
||||||
|
ai2 = Marshal.load(Marshal.dump(ai1))
|
||||||
|
assert_equal(ai1.afamily, ai2.afamily)
|
||||||
|
assert_equal(ai1.ip_unpack, ai2.ip_unpack)
|
||||||
|
assert_equal(ai1.pfamily, ai2.pfamily)
|
||||||
|
assert_equal(ai1.socktype, ai2.socktype)
|
||||||
|
assert_equal(ai1.protocol, ai2.protocol)
|
||||||
|
assert_equal(ai1.canonname, ai2.canonname)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if defined?(UNIXSocket) && /cygwin/ !~ RUBY_PLATFORM
|
if defined?(UNIXSocket) && /cygwin/ !~ RUBY_PLATFORM
|
||||||
@ -325,5 +347,16 @@ class TestSocketAddrInfo < Test::Unit::TestCase
|
|||||||
assert(unix_ai.unix?)
|
assert(unix_ai.unix?)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_marshal_unix
|
||||||
|
ai1 = AddrInfo.unix("/var/tmp/sock")
|
||||||
|
ai2 = Marshal.load(Marshal.dump(ai1))
|
||||||
|
assert_equal(ai1.afamily, ai2.afamily)
|
||||||
|
assert_equal(ai1.unix_path, ai2.unix_path)
|
||||||
|
assert_equal(ai1.pfamily, ai2.pfamily)
|
||||||
|
assert_equal(ai1.socktype, ai2.socktype)
|
||||||
|
assert_equal(ai1.protocol, ai2.protocol)
|
||||||
|
assert_equal(ai1.canonname, ai2.canonname)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user