return (((uint8_t *)a1)[l] & mask[r]) == (((uint8_t *)a2)[l] & mask[r]);
}
-int addressmatches(struct list *hostports, struct sockaddr *addr) {
+int addressmatches(struct list *hostports, struct sockaddr *addr, uint8_t checkport) {
struct sockaddr_in6 *sa6 = NULL;
struct in_addr *a4 = NULL;
struct addrinfo *res;
for (res = hp->addrinfo; res; res = res->ai_next)
if (hp->prefixlen == 255) {
if ((a4 && res->ai_family == AF_INET &&
- !memcmp(a4, &((struct sockaddr_in *)res->ai_addr)->sin_addr, 4)) ||
+ !memcmp(a4, &((struct sockaddr_in *)res->ai_addr)->sin_addr, 4) &&
+ (!checkport || ((struct sockaddr_in *)res->ai_addr)->sin_port ==
+ ((struct sockaddr_in *)addr)->sin_port)) ||
(sa6 && res->ai_family == AF_INET6 &&
- !memcmp(&sa6->sin6_addr, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 16)))
+ !memcmp(&sa6->sin6_addr,
+ &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 16) &&
+ (!checkport || ((struct sockaddr_in6 *)res->ai_addr)->sin6_port ==
+ ((struct sockaddr_in6 *)addr)->sin6_port)))
return 1;
} else {
if ((a4 && res->ai_family == AF_INET &&
int resolvehostport(struct hostportres *hp, int socktype, uint8_t passive);
int resolvehostports(struct list *hostports, int socktype);
struct addrinfo *resolvepassiveaddrinfo(char *hostport, char *default_port, int socktype);
-int addressmatches(struct list *hostports, struct sockaddr *addr);
+int addressmatches(struct list *hostports, struct sockaddr *addr, uint8_t checkport);
int connecttcphostlist(struct list *hostports, struct addrinfo *src);
}
/* returns next config with matching address, or NULL */
-struct clsrvconf *find_conf(uint8_t type, struct sockaddr *addr, struct list *confs, struct list_node **cur) {
+struct clsrvconf *find_conf(uint8_t type, struct sockaddr *addr, struct list *confs, struct list_node **cur, uint8_t server_p) {
struct list_node *entry;
struct clsrvconf *conf;
for (entry = (cur && *cur ? list_next(*cur) : list_first(confs)); entry; entry = list_next(entry)) {
conf = (struct clsrvconf *)entry->data;
- if (conf->type == type && addressmatches(conf->hostports, addr)) {
+ if (conf->type == type && addressmatches(conf->hostports, addr, server_p)) {
if (cur)
*cur = entry;
return conf;
}
struct clsrvconf *find_clconf(uint8_t type, struct sockaddr *addr, struct list_node **cur) {
- return find_conf(type, addr, clconfs, cur);
+ return find_conf(type, addr, clconfs, cur, 0);
}
struct clsrvconf *find_srvconf(uint8_t type, struct sockaddr *addr, struct list_node **cur) {
- return find_conf(type, addr, srvconfs, cur);
+ return find_conf(type, addr, srvconfs, cur, 1);
}
/* returns next config of given type, or NULL */