guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

socket address and name lookup support in guile


From: Ken Raeburn
Subject: socket address and name lookup support in guile
Date: Mon, 15 Oct 2001 02:05:57 -0400

I'm looking at adding support for ipv6 address lookup to guile
(forward and reverse), since while there's ipv6 socket support, it
appears that name lookup is limited to ipv4 still.

A few things have come up that I'd like comments on:

1- which interface to provide

In the IETF (see, for example, RFC 2553 and the draft update to it),
gethostby* and getservby* are deprecated (or at least seem to be
heading down that road), and getaddrinfo and getnameinfo are the
recommended APIs.  They avoid hidden static data; they're supposed to
be thread-safe; they handle multiple address families.

My own personal feeling is that inet_lnaof, sethostent, and the like
have been obsolete for years, since the widespread use of CIDR and DNS
respectively.  Does anyone actually use them any more?  Is guile
providing them for any reason other than they're still part of the C
library API?

The current Guile approach in many areas seems to be to provide a thin
layer over the provided C library routines.  But should a Guile
application that wants to support IPv6 when available have to check to
see whether getaddrinfo is available and decide whether to use it vs
gethostbyname?  Or should I provide an updated API always, that
supports multiple address families, and bury the fallback to IPv4-only
and gethostbyname in the implementation?

I'm inclined to do the latter, which leads to the next question:

1A- What should that API be?

 + Enhance the "gethost"/"getserv" interfaces, thus continuing to
   encourage use of the old interfaces.

 + Provide "getaddrinfo" and "getnameinfo".  The interfaces aren't as
   simple as gethostby*; for example, getaddrinfo accepts several
   flags and some non-flag options such as address family.  (I haven't
   worked out how to represent the options yet.)

 + Provide a single routine the way that "gethost" covers both
   gethostbyname and gethostbyaddr?  I'm not even sure what this one
   would look like; the arguments accepted would have to depend on
   which direction you wanted to do the lookup.

I think the second option is the best, personally.  Which brings me
to:

1B- multiple APIs or one

If I provide a new API, and make it available always, even when it's a
fake implementation over gethostby*/getservby*, should the
gethost/getserv implementation be kept as is, or should I replace them
with Scheme code that invokes the new routines?  Replacing them would
reduce code size.

Caveat: Old GNU libc implementations (such as in Red Hat 6.1) have
buggy implementations of getaddrinfo that under some circumstances
(which I haven't nailed down, but seem to be: multiple IPv4 addresses
AND at least one IPv6 address AND no service name specified), it
doesn't return all the IPv4 addresses.  I think the best way to deal
with this is to try to detect the old glibc and fall back to
gethostbyname instead, abandoning the ipv6 lookup, or maybe use both
gethostbyname and getaddrinfo and eliminate duplicates, rather than
providing two APIs that give different answers.

2- format of socket address

Why do some functions in socket.c use lists of sockaddr fields
(namely, as trailing arguments in calls), and some use vectors
(getpeername for example)?

I'd really like to be able to have getaddrinfo return something that
can be passed to getnameinfo without having to change the format and
create a new object.  But getnameinfo should of course accept the
value returned by getpeername, too.  Do I really have to make
getnameinfo accept both list and vector forms for smooth operation?

I assume it's too late to change either representation already in use?

3- MAX_ADDR_SIZE ?

Is there some reason a union of the relevant types wouldn't work?  I
haven't traced through enough to be sure, but the current char-array
stuff makes me worry about alignment issues.  Offhand, I don't think a
char array automatic variable needs to be aligned very strictly;
depending how it's used, a sockaddr might.  Unless the char array is
in fact required to be aligned strictly, let's not rely on the
generosity of a particular compiler more than we need to.

Ken

P.S.  I have some preliminary code working:

guile> (getaddrinfo "raeburn.org" "telnet")
(#(2 2457040922 23) #(2 308609249 23) #(10 
85060792870324214533364784363651203073 23 0 0) #(10 
42548650839044833122330995083387600897 23 0 0))
guile> (lookup "raeburn.org" "telnet")
address in family 2:    146.115.120.26
address in family 2:    18.101.0.225
address in family 10:   3ffe:1ce1:0:fe30::1
address in family 10:   2002:9273:781a::1
#f
guile> 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]