X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=http_send.c;h=28e245eae13ac6b7ce8e0a5f162ab88be52b5a60;hp=33d5ed934dc3cfc05117a991be02dc9f1d2cfc6c;hb=78200714a07173565ecff4adc8d12b87895017f3;hpb=73f02f72cb49baebff3e0f6946750a5bc0693321 diff --git a/http_send.c b/http_send.c index 33d5ed93..28e245ea 100644 --- a/http_send.c +++ b/http_send.c @@ -202,24 +202,37 @@ static void http_send( long unsigned current_chunk, } } +/** + * Return true if addr_1 matches addr_2 in the first `netmask' bits. + */ +static int v4_addr_match(uint32_t addr_1, uint32_t addr_2, uint8_t netmask) +{ + uint32_t mask = ~0U; + + if (netmask < 32) + mask <<= (32 - netmask); + return (htonl(addr_1) & mask) == (htonl(addr_2) & mask); +} + static int host_in_access_perm_list(struct http_client *hc) { - struct sockaddr_storage ss; - socklen_t sslen = sizeof(ss); + struct access_info *ai, *tmp; + struct sockaddr_storage ss; + socklen_t sslen = sizeof(ss); + struct in_addr v4_addr; if (getpeername(hc->fd, (struct sockaddr *)&ss, &sslen) < 0) { - PARA_ERROR_LOG("can not determine address family: %s\n", strerror(errno)); - } else if (ss.ss_family == AF_INET) { - /* FIXME: access restriction is (currently) only supported for IPv4 */ - struct access_info *ai, *tmp; - struct in_addr client_addr = ((struct sockaddr_in *)&ss)->sin_addr; - - list_for_each_entry_safe(ai, tmp, &access_perm_list, node) { - unsigned mask = ((~0U) >> ai->netmask); - if ((client_addr.s_addr & mask) == (ai->addr.s_addr & mask)) - return 1; - } + PARA_ERROR_LOG("Can not determine peer address: %s\n", strerror(errno)); + goto no_match; } + v4_addr = extract_v4_addr(&ss); + if (!v4_addr.s_addr) + goto no_match; + + list_for_each_entry_safe(ai, tmp, &access_perm_list, node) + if (v4_addr_match(v4_addr.s_addr, ai->addr.s_addr, ai->netmask)) + return 1; +no_match: return 0; }