mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 11:40:18 +02:00
* some initial support for IPv6:
* socket.c (scm_fill_sockaddr): improve the argument validation. don't allocate memory until all args are checked. instead of unconditional memset of soka, try setting sin_len to 0 if SIN_LEN is defined. add support for AF_INET6. define FUNC_NAME. (scm_socket, scm_connect): extend docstrings for IPv6. (scm_init_socket): intern AF_INET6 and PF_INET6.
This commit is contained in:
parent
5b079b46d2
commit
3453619bd3
2 changed files with 120 additions and 21 deletions
|
@ -1,3 +1,14 @@
|
||||||
|
2001-04-17 Gary Houston <ghouston@arglist.com>
|
||||||
|
|
||||||
|
* some initial support for IPv6:
|
||||||
|
|
||||||
|
* socket.c (scm_fill_sockaddr): improve the argument validation.
|
||||||
|
don't allocate memory until all args are checked. instead of
|
||||||
|
unconditional memset of soka, try setting sin_len to 0 if
|
||||||
|
SIN_LEN is defined. add support for AF_INET6. define FUNC_NAME.
|
||||||
|
(scm_socket, scm_connect): extend docstrings for IPv6.
|
||||||
|
(scm_init_socket): intern AF_INET6 and PF_INET6.
|
||||||
|
|
||||||
2001-04-17 Niibe Yutaka <gniibe@m17n.org>
|
2001-04-17 Niibe Yutaka <gniibe@m17n.org>
|
||||||
|
|
||||||
* srcprop.c (scm_make_srcprops): Added SCM_ALLOW_INTS which
|
* srcprop.c (scm_make_srcprops): Added SCM_ALLOW_INTS which
|
||||||
|
|
|
@ -148,9 +148,9 @@ SCM_DEFINE (scm_socket, "socket", 3, 0, 0,
|
||||||
(SCM family, SCM style, SCM proto),
|
(SCM family, SCM style, SCM proto),
|
||||||
"Return a new socket port of the type specified by @var{family},\n"
|
"Return a new socket port of the type specified by @var{family},\n"
|
||||||
"@var{style} and @var{protocol}. All three parameters are\n"
|
"@var{style} and @var{protocol}. All three parameters are\n"
|
||||||
"integers. Typical values for @var{family} are the values of\n"
|
"integers. Supported values for @var{family} are\n"
|
||||||
"@code{AF_UNIX} and @code{AF_INET}. Typical values for\n"
|
"@code{AF_UNIX}, @code{AF_INET} and @code{AF_INET6}.\n"
|
||||||
"@var{style} are the values of @code{SOCK_STREAM},\n"
|
"Typical values for @var{style} are @code{SOCK_STREAM},\n"
|
||||||
"@code{SOCK_DGRAM} and @code{SOCK_RAW}.\n"
|
"@code{SOCK_DGRAM} and @code{SOCK_RAW}.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"@var{protocol} can be obtained from a protocol name using\n"
|
"@var{protocol} can be obtained from a protocol name using\n"
|
||||||
|
@ -407,31 +407,106 @@ SCM_DEFINE (scm_shutdown, "shutdown", 2, 0, 0,
|
||||||
static struct sockaddr *
|
static struct sockaddr *
|
||||||
scm_fill_sockaddr (int fam, SCM address, SCM *args, int which_arg,
|
scm_fill_sockaddr (int fam, SCM address, SCM *args, int which_arg,
|
||||||
const char *proc, int *size)
|
const char *proc, int *size)
|
||||||
|
#define FUNC_NAME proc
|
||||||
{
|
{
|
||||||
switch (fam)
|
switch (fam)
|
||||||
{
|
{
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
{
|
{
|
||||||
SCM isport;
|
|
||||||
struct sockaddr_in *soka;
|
struct sockaddr_in *soka;
|
||||||
|
unsigned long addr;
|
||||||
|
int port;
|
||||||
|
|
||||||
SCM_ASSERT (SCM_CONSP (*args), *args,
|
SCM_VALIDATE_ULONG_COPY (which_arg, address, addr);
|
||||||
which_arg + 1, proc);
|
SCM_VALIDATE_CONS (which_arg + 1, *args);
|
||||||
isport = SCM_CAR (*args);
|
SCM_VALIDATE_INUM_COPY (which_arg + 1, SCM_CAR (*args), port);
|
||||||
SCM_ASSERT (SCM_INUMP (isport), isport, which_arg + 1, proc);
|
*args = SCM_CDR (*args);
|
||||||
soka = (struct sockaddr_in *) malloc (sizeof (struct sockaddr_in));
|
soka = (struct sockaddr_in *) malloc (sizeof (struct sockaddr_in));
|
||||||
if (!soka)
|
if (!soka)
|
||||||
scm_memory_error (proc);
|
scm_memory_error (proc);
|
||||||
/* e.g., for BSDs which don't like invalid sin_len. */
|
/* 4.4BSD-style interface includes sin_len member and defines SIN_LEN,
|
||||||
memset (soka, 0, sizeof (struct sockaddr_in));
|
4.3BSD does not. */
|
||||||
|
#ifdef SIN_LEN
|
||||||
|
soka->sin_len = sizeof (struct sockaddr_in);
|
||||||
|
#endif
|
||||||
soka->sin_family = AF_INET;
|
soka->sin_family = AF_INET;
|
||||||
soka->sin_addr.s_addr =
|
soka->sin_addr.s_addr = htonl (addr);
|
||||||
htonl (scm_num2ulong (address, which_arg, proc));
|
soka->sin_port = htons (port);
|
||||||
*args = SCM_CDR (*args);
|
|
||||||
soka->sin_port = htons (SCM_INUM (isport));
|
|
||||||
*size = sizeof (struct sockaddr_in);
|
*size = sizeof (struct sockaddr_in);
|
||||||
return (struct sockaddr *) soka;
|
return (struct sockaddr *) soka;
|
||||||
}
|
}
|
||||||
|
#ifdef AF_INET6
|
||||||
|
case AF_INET6:
|
||||||
|
{
|
||||||
|
/* see RFC2553. */
|
||||||
|
int port;
|
||||||
|
struct sockaddr_in6 *soka;
|
||||||
|
unsigned long flowinfo = 0;
|
||||||
|
unsigned long scope_id = 0;
|
||||||
|
|
||||||
|
if (SCM_INUMP (address))
|
||||||
|
SCM_ASSERT_RANGE (which_arg, address, SCM_INUM (address) >= 0);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SCM_VALIDATE_BIGINT (which_arg, address);
|
||||||
|
SCM_ASSERT_RANGE (which_arg, address,
|
||||||
|
!SCM_BIGSIGN (address)
|
||||||
|
&& (SCM_BITSPERDIG
|
||||||
|
* SCM_NUMDIGS (address) <= 128));
|
||||||
|
}
|
||||||
|
SCM_VALIDATE_CONS (which_arg + 1, *args);
|
||||||
|
SCM_VALIDATE_INUM_COPY (which_arg + 1, SCM_CAR (*args), port);
|
||||||
|
*args = SCM_CDR (*args);
|
||||||
|
if (SCM_CONSP (*args))
|
||||||
|
{
|
||||||
|
SCM_VALIDATE_ULONG_COPY (which_arg + 2, SCM_CAR (*args), flowinfo);
|
||||||
|
*args = SCM_CDR (*args);
|
||||||
|
if (SCM_CONSP (*args))
|
||||||
|
{
|
||||||
|
SCM_VALIDATE_ULONG_COPY (which_arg + 3, SCM_CAR (*args),
|
||||||
|
scope_id);
|
||||||
|
*args = SCM_CDR (*args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
soka = (struct sockaddr_in6 *) malloc (sizeof (struct sockaddr_in6));
|
||||||
|
if (!soka)
|
||||||
|
scm_memory_error (proc);
|
||||||
|
#ifdef SIN_LEN6
|
||||||
|
soka->sin6_len = sizeof (struct sockaddr_in6);
|
||||||
|
#endif
|
||||||
|
soka->sin6_family = AF_INET6;
|
||||||
|
if (SCM_INUMP (address))
|
||||||
|
{
|
||||||
|
uint32_t addr = htonl (SCM_INUM (address));
|
||||||
|
|
||||||
|
memset (soka->sin6_addr.s6_addr, 0, 12);
|
||||||
|
memcpy (soka->sin6_addr.s6_addr + 12, &addr, 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scm_sizet i;
|
||||||
|
|
||||||
|
memset (soka->sin6_addr.s6_addr, 0, 16);
|
||||||
|
memcpy (soka->sin6_addr.s6_addr, SCM_BDIGITS (address),
|
||||||
|
SCM_NUMDIGS (address) * (SCM_BITSPERDIG / 8));
|
||||||
|
#ifndef WORDS_BIGENDIAN
|
||||||
|
/* flip to network order. */
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
char c = soka->sin6_addr.s6_addr[i];
|
||||||
|
|
||||||
|
soka->sin6_addr.s6_addr[i] = soka->sin6_addr.s6_addr[15 - i];
|
||||||
|
soka->sin6_addr.s6_addr[15 - i] = c;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
soka->sin6_port = port;
|
||||||
|
soka->sin6_flowinfo = flowinfo;
|
||||||
|
soka->sin6_scope_id = scope_id;
|
||||||
|
*size = sizeof (struct sockaddr_in6);
|
||||||
|
return (struct sockaddr *) soka;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#ifdef HAVE_UNIX_DOMAIN_SOCKETS
|
#ifdef HAVE_UNIX_DOMAIN_SOCKETS
|
||||||
case AF_UNIX:
|
case AF_UNIX:
|
||||||
{
|
{
|
||||||
|
@ -462,19 +537,26 @@ scm_fill_sockaddr (int fam, SCM address, SCM *args, int which_arg,
|
||||||
scm_out_of_range (proc, SCM_MAKINUM (fam));
|
scm_out_of_range (proc, SCM_MAKINUM (fam));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#undef FUNC_NAME
|
||||||
|
|
||||||
SCM_DEFINE (scm_connect, "connect", 3, 0, 1,
|
SCM_DEFINE (scm_connect, "connect", 3, 0, 1,
|
||||||
(SCM sock, SCM fam, SCM address, SCM args),
|
(SCM sock, SCM fam, SCM address, SCM args),
|
||||||
"Initiates a connection from @var{socket} to the address\n"
|
"Initiates a connection from a socket using a specified address\n"
|
||||||
"specified by @var{address} and possibly @var{arg @dots{}}. The format\n"
|
"family to the address\n"
|
||||||
"required for @var{address}\n"
|
"specified by @var{address} and possibly @var{args}.\n"
|
||||||
"and @var{arg} @dots{} depends on the family of the socket.\n\n"
|
"The format required for @var{address}\n"
|
||||||
|
"and @var{args} depends on the family of the socket.\n\n"
|
||||||
"For a socket of family @code{AF_UNIX},\n"
|
"For a socket of family @code{AF_UNIX},\n"
|
||||||
"only @code{address} is specified and must be a string with the\n"
|
"only @var{address} is specified and must be a string with the\n"
|
||||||
"filename where the socket is to be created.\n\n"
|
"filename where the socket is to be created.\n\n"
|
||||||
"For a socket of family @code{AF_INET},\n"
|
"For a socket of family @code{AF_INET},\n"
|
||||||
"@code{address} must be an integer Internet host address and @var{arg} @dots{}\n"
|
"@var{address} must be an integer IPv4 host address and\n"
|
||||||
"must be a single integer port number.\n\n"
|
"@var{args} must be a single integer port number.\n\n"
|
||||||
|
"For a socket of family @code{AF_INET6},\n"
|
||||||
|
"@var{address} must be an integer IPv6 host address and\n"
|
||||||
|
"@var{args} may be up to three integers:\n"
|
||||||
|
"port [flowinfo] [scope_id],\n"
|
||||||
|
"where flowinfo and scope_id default to zero.\n\n"
|
||||||
"The return value is unspecified.")
|
"The return value is unspecified.")
|
||||||
#define FUNC_NAME s_scm_connect
|
#define FUNC_NAME s_scm_connect
|
||||||
{
|
{
|
||||||
|
@ -906,6 +988,9 @@ scm_init_socket ()
|
||||||
#ifdef AF_INET
|
#ifdef AF_INET
|
||||||
scm_sysintern ("AF_INET", SCM_MAKINUM (AF_INET));
|
scm_sysintern ("AF_INET", SCM_MAKINUM (AF_INET));
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef AF_INET6
|
||||||
|
scm_sysintern ("AF_INET6", SCM_MAKINUM (AF_INET6));
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef PF_UNSPEC
|
#ifdef PF_UNSPEC
|
||||||
scm_sysintern ("PF_UNSPEC", SCM_MAKINUM (PF_UNSPEC));
|
scm_sysintern ("PF_UNSPEC", SCM_MAKINUM (PF_UNSPEC));
|
||||||
|
@ -916,6 +1001,9 @@ scm_init_socket ()
|
||||||
#ifdef PF_INET
|
#ifdef PF_INET
|
||||||
scm_sysintern ("PF_INET", SCM_MAKINUM (PF_INET));
|
scm_sysintern ("PF_INET", SCM_MAKINUM (PF_INET));
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef PF_INET6
|
||||||
|
scm_sysintern ("PF_INET6", SCM_MAKINUM (PF_INET6));
|
||||||
|
#endif
|
||||||
|
|
||||||
/* socket types. */
|
/* socket types. */
|
||||||
#ifdef SOCK_STREAM
|
#ifdef SOCK_STREAM
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue