fixes on sockaddr presentation; now v6 service port reports v4mapped addresses as if they are v4.

git-svn-id: http://repo.ham.fi/svn/aprsc/trunk@242 3ce903b1-3385-4e86-93cd-f9a4a239f7ac
This commit is contained in:
Matti Aarnio 2008-03-25 15:10:56 +00:00
parent 99e01ca3a9
commit 12563910cf
4 changed files with 64 additions and 39 deletions

View File

@ -200,6 +200,7 @@ int open_udp_listener(struct listen_t *l, const struct addrinfo *ai)
c = client_udp_alloc(fd, l->portnum);
c->portaccount = l->portaccount;
inbound_connects_account(3, c->portaccount); /* "3" = udp, not listening..
account all ports + port-specifics */
@ -218,6 +219,7 @@ int open_udp_listener(struct listen_t *l, const struct addrinfo *ai)
so it doesn't really even matter if it fails. */
l->udp = c;
/* l->fd = fd -- except that close on it will kill working client setups.. */
return fd;
}
@ -239,7 +241,7 @@ int open_listeners(void)
/* Pick first of the AIs for this listen definition */
l->addr_s = strsockaddr( (void*)lc->ai->ai_addr, lc->ai->ai_addrlen );
l->addr_s = strsockaddr( lc->ai->ai_addr, lc->ai->ai_addrlen );
l->name = hstrdup(lc->name);
if (lc->ai->ai_socktype == SOCK_DGRAM &&
@ -307,24 +309,22 @@ struct client_t *do_accept(struct listen_t *l)
struct client_t *c;
union sockaddr_u sa; /* large enough for also IPv6 address */
socklen_t addr_len = sizeof(sa);
char eb[200];
char sbuf[20];
char *s;
char buf[2000];
static int next_receiving_worker;
struct worker_t *w;
struct worker_t *wc;
static time_t last_EMFILE_report;
if (l->udp) {
union sockaddr_u sa;
socklen_t fromlen = sizeof(sa);
while (l->udp) {
/* Received data will be discarded, so receiving it */
/* TRUNCATED is just fine */
i = recvfrom( l->udp->fd, eb, sizeof(eb),
MSG_DONTWAIT|MSG_TRUNC,
& sa.sa, & fromlen );
return 0;
/* TRUNCATED is just fine. Sender isn't interesting either. */
/* Receive as much as there is -- that is, LOOP... */
i = recv( l->udp->fd, buf, sizeof(buf), MSG_DONTWAIT|MSG_TRUNC );
if (i < 0)
return 0; /* no more data */
}
if ((fd = accept(l->fd, (struct sockaddr*)&sa, &addr_len)) < 0) {
@ -380,24 +380,16 @@ struct client_t *do_accept(struct listen_t *l)
/* text format of client's IP address + port */
c->addr_s = strsockaddr( &sa, addr_len );
c->addr_s = strsockaddr( &sa.sa, addr_len );
/* text format of servers' connected IP address + port */
addr_len = sizeof(sa);
if (getsockname(fd, &sa.sa, &addr_len) == 0) {
eb[0] = '[';
eb[1] = 0;
*sbuf = 0;
getnameinfo( & sa.sa, addr_len,
eb+1, sizeof(eb)-1, sbuf, sizeof(sbuf), NI_NUMERICHOST|NI_NUMERICSERV);
s = eb + strlen(eb);
sprintf(s, "]:%s", sbuf);
c->addr_ss = hstrdup(eb); /* Server's bound IP address */
if (getsockname(fd, &sa.sa, &addr_len) == 0) { /* Fails very rarely.. */
/* present my socket end address as a malloced string... */
c->addr_ss = strsockaddr( &sa.sa, addr_len );
} else {
c->addr_ss = hstrdup(l->addr_s); /* Server's bound IP address */
c->addr_ss = hstrdup( l->addr_s ); /* Server's bound IP address */
}
@ -417,7 +409,7 @@ struct client_t *do_accept(struct listen_t *l)
if (c->flags & CLFLAGS_UPLINKSIM)
uplink_simulator = 1;
hlog(LOG_DEBUG, "%s - Accepted connection on fd %d from %s", l->addr_s, c->fd, eb);
hlog(LOG_DEBUG, "%s - Accepted connection on fd %d from %s", l->addr_s, c->fd, c->addr_ss);
for (i = 0; i < (sizeof(l->filters)/sizeof(l->filters[0])); ++i) {
if (l->filters[i])
@ -538,8 +530,9 @@ void accept_thread(void *asdf)
acceptpfd = hmalloc(listen_n * sizeof(*acceptpfd));
n = 0;
for (l = listen_list; (l); l = l->next) {
hlog(LOG_DEBUG, "... %d: fd %d (%s)", n, l->fd, l->addr_s);
acceptpfd[n].fd = l->fd;
int fd = l->udp ? l->udp->fd : l->fd;
hlog(LOG_DEBUG, "... %d: fd %d (%s)", n, fd, l->addr_s);
acceptpfd[n].fd = fd;
acceptpfd[n].events = POLLIN|POLLPRI|POLLERR|POLLHUP;
n++;
}
@ -572,7 +565,7 @@ void accept_thread(void *asdf)
/* now, which socket was that on? */
l = listen_list;
for (n = 0; n < listen_n; n++) {
if (!(l) || l->fd != acceptpfd[n].fd) {
if (!(l) || (l->udp ? l->udp->fd : l->fd) != acceptpfd[n].fd) {
hlog(LOG_CRIT, "accept_thread: polling list and listener list do mot match!");
exit(1);
}

View File

@ -242,7 +242,7 @@ int make_uplink(struct uplink_config_t *l)
c->fd = fd;
c->addr = sa;
c->state = CSTATE_CONNECTED;
c->addr_s = strsockaddr( &sa, addr_len );
c->addr_s = strsockaddr( &sa.sa, addr_len );
c->keepalive = now;
/* use the default login handler */
c->handler = & uplink_login_handler;

View File

@ -282,20 +282,52 @@ void client_free(struct client_t *c)
}
char *strsockaddr(const union sockaddr_u *sa, const int addr_len)
char *strsockaddr(const struct sockaddr *sa, const int addr_len)
{
char eb[200], *s;
char sbuf[20];
union sockaddr_u su, *sup;
eb[0] = '[';
eb[1] = 0;
*sbuf = 0;
sup = (union sockaddr_u *)sa;
#ifdef IN6_IS_ADDR_V4MAPPED
if ( sa->sa_family == AF_INET6 &&
( IN6_IS_ADDR_V4MAPPED(&(sup->si6.sin6_addr)) ||
IN6_IS_ADDR_V4COMPAT(&(sup->si6.sin6_addr)) ) ) {
getnameinfo((struct sockaddr *)&sa, addr_len,
eb+1, sizeof(eb)-1, sbuf, sizeof(sbuf), NI_NUMERICHOST|NI_NUMERICSERV);
s = eb + strlen(eb);
memset(&su, 0, sizeof(su));
su.si.sin_family = AF_INET;
su.si.sin_port = sup->si6.sin6_port;
memcpy(& su.si.sin_addr, &((uint32_t*)(&(sup->si6.sin6_addr)))[3], 4);
sa = &su.sa;
sup = NULL;
hlog(LOG_DEBUG, "Translating v4 mapped/compat address..");
}
#endif
sprintf(s, "]:%s", sbuf);
if ( sa->sa_family == AF_INET ) {
eb[0] = 0;
sbuf[0] = 0;
getnameinfo( sa, addr_len,
eb, sizeof(eb), sbuf, sizeof(sbuf), NI_NUMERICHOST|NI_NUMERICSERV);
s = eb + strlen(eb);
sprintf(s, ":%s", sbuf);
} else {
/* presumption: IPv6 */
eb[0] = '[';
eb[1] = 0;
sbuf[0] = 0;
getnameinfo( sa, addr_len,
eb+1, sizeof(eb)-1, sbuf, sizeof(sbuf), NI_NUMERICHOST|NI_NUMERICSERV);
s = eb + strlen(eb);
sprintf(s, "]:%s", sbuf);
}
if (!sup) hlog(LOG_DEBUG, "... to: %s", eb);
return hstrdup(eb);
}

View File

@ -329,6 +329,6 @@ extern struct portaccount_t *port_accounter_alloc(void);
extern void port_accounter_add(struct portaccount_t *p);
extern void port_accounter_drop(struct portaccount_t *p);
extern char *strsockaddr(const union sockaddr_u *sa, const int addr_len);
extern char *strsockaddr(const struct sockaddr *sa, const int addr_len);
#endif