tcp/udp: IPv6 scope-id support for link-local addresses

This commit is contained in:
Richard Aas 2012-08-03 12:55:15 +00:00
parent 8428a0ad62
commit e63acdb2ff
6 changed files with 63 additions and 25 deletions

View file

@ -57,3 +57,6 @@ bool sa_cmp(const struct sa *l, const struct sa *r, int flag);
bool sa_is_linklocal(const struct sa *sa);
bool sa_is_loopback(const struct sa *sa);
bool sa_is_any(const struct sa *sa);
struct re_printf;
int sa_print_addr(struct re_printf *pf, const struct sa *sa);

View file

@ -109,6 +109,7 @@ SOURCE source.c
SOURCEPATH ..\..\src\sa
SOURCE ntop.c
SOURCE print.c
SOURCE pton.c
SOURCE sa.c

View file

@ -5,5 +5,6 @@
#
SRCS += sa/ntop.c
SRCS += sa/print.c
SRCS += sa/pton.c
SRCS += sa/sa.c

39
src/sa/print.c Normal file
View file

@ -0,0 +1,39 @@
/**
* @file sa/print.c Socket Address printing
*
* Copyright (C) 2010 Creytiv.com
*/
#ifdef HAVE_GETIFADDRS
#include <sys/types.h>
#include <sys/socket.h>
#define __USE_MISC 1 /**< Use MISC code */
#include <net/if.h>
#endif
#include <re_types.h>
#include <re_fmt.h>
#include <re_sa.h>
int sa_print_addr(struct re_printf *pf, const struct sa *sa)
{
int err;
if (!sa)
return 0;
err = re_hprintf(pf, "%j", sa);
#ifdef HAVE_GETIFADDRS
if (sa_af(sa) == AF_INET6 && sa_is_linklocal(sa)) {
char ifname[IF_NAMESIZE];
if (!if_indextoname(sa->u.in6.sin6_scope_id, ifname))
return errno;
err |= re_hprintf(pf, "%%%s", ifname);
}
#endif
return err;
}

View file

@ -566,7 +566,7 @@ int tcp_sock_alloc(struct tcp_sock **tsp, const struct sa *local,
tcp_conn_h *ch, void *arg)
{
struct addrinfo hints, *res = NULL, *r;
char addr[NET_ADDRSTRLEN] = "";
char addr[64] = "";
char serv[6] = "0";
struct tcp_sock *ts = NULL;
int error, err;
@ -582,10 +582,9 @@ int tcp_sock_alloc(struct tcp_sock **tsp, const struct sa *local,
ts->fdc = -1;
if (local) {
err = sa_ntop(local, addr, sizeof(addr));
(void)re_snprintf(addr, sizeof(addr), "%H",
sa_print_addr, local);
(void)re_snprintf(serv, sizeof(serv), "%u", sa_port(local));
if (err)
goto out;
}
memset(&hints, 0, sizeof(hints));
@ -667,7 +666,7 @@ int tcp_sock_alloc(struct tcp_sock **tsp, const struct sa *local,
int tcp_sock_bind(struct tcp_sock *ts, const struct sa *local)
{
struct addrinfo hints, *res = NULL, *r;
char addr[NET_ADDRSTRLEN] = "";
char addr[64] = "";
char serv[NI_MAXSERV] = "0";
int error, err;
@ -675,10 +674,9 @@ int tcp_sock_bind(struct tcp_sock *ts, const struct sa *local)
return EINVAL;
if (local) {
err = sa_ntop(local, addr, sizeof(addr));
(void)re_snprintf(addr, sizeof(addr), "%H",
sa_print_addr, local);
(void)re_snprintf(serv, sizeof(serv), "%u", sa_port(local));
if (err)
return err;
}
memset(&hints, 0, sizeof(hints));
@ -829,7 +827,7 @@ int tcp_conn_alloc(struct tcp_conn **tcp,
{
struct tcp_conn *tc;
struct addrinfo hints, *res = NULL, *r;
char addr[NET_ADDRSTRLEN];
char addr[64];
char serv[NI_MAXSERV] = "0";
int error, err;
@ -847,10 +845,9 @@ int tcp_conn_alloc(struct tcp_conn **tcp,
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
err = sa_ntop(peer, addr, sizeof(addr));
(void)re_snprintf(addr, sizeof(addr), "%H",
sa_print_addr, peer);
(void)re_snprintf(serv, sizeof(serv), "%u", sa_port(peer));
if (err)
goto out;
error = getaddrinfo(addr, serv, &hints, &res);
if (error) {
@ -908,7 +905,7 @@ int tcp_conn_alloc(struct tcp_conn **tcp,
int tcp_conn_bind(struct tcp_conn *tc, const struct sa *local)
{
struct addrinfo hints, *res = NULL, *r;
char addr[NET_ADDRSTRLEN] = "";
char addr[64] = "";
char serv[NI_MAXSERV] = "0";
int error, err;
@ -916,10 +913,9 @@ int tcp_conn_bind(struct tcp_conn *tc, const struct sa *local)
return EINVAL;
if (local) {
err = sa_ntop(local, addr, sizeof(addr));
(void)re_snprintf(addr, sizeof(addr), "%H",
sa_print_addr, local);
(void)re_snprintf(serv, sizeof(serv), "%u", sa_port(local));
if (err)
return err;
}
memset(&hints, 0, sizeof(hints));
@ -983,9 +979,9 @@ int tcp_conn_bind(struct tcp_conn *tc, const struct sa *local)
int tcp_conn_connect(struct tcp_conn *tc, const struct sa *peer)
{
struct addrinfo hints, *res = NULL, *r;
char addr[NET_ADDRSTRLEN];
char addr[64];
char serv[NI_MAXSERV];
int error, err;
int error, err = 0;
if (!tc || !sa_isset(peer, SA_ALL))
return EINVAL;
@ -1004,10 +1000,9 @@ int tcp_conn_connect(struct tcp_conn *tc, const struct sa *peer)
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
err = sa_ntop(peer, addr, sizeof(addr));
(void)re_snprintf(addr, sizeof(addr), "%H",
sa_print_addr, peer);
(void)re_snprintf(serv, sizeof(serv), "%u", sa_port(peer));
if (err)
return err;
error = getaddrinfo(addr, serv, &hints, &res);
if (error) {

View file

@ -262,7 +262,7 @@ int udp_listen(struct udp_sock **usp, const struct sa *local,
{
struct addrinfo hints, *res = NULL, *r;
struct udp_sock *us = NULL;
char addr[NET_ADDRSTRLEN];
char addr[64];
char serv[6] = "0";
int af, error, err = 0;
@ -280,10 +280,9 @@ int udp_listen(struct udp_sock **usp, const struct sa *local,
if (local) {
af = sa_af(local);
err = sa_ntop(local, addr, sizeof(addr));
(void)re_snprintf(addr, sizeof(addr), "%H",
sa_print_addr, local);
(void)re_snprintf(serv, sizeof(serv), "%u", sa_port(local));
if (err)
goto out;
}
else {
#ifdef HAVE_INET6