mirror of https://github.com/getdnsapi/getdns.git
Issue #430: Record and guard UDP max payload size with servers.
This commit is contained in:
parent
971c43c659
commit
6cb15939ba
|
@ -1,6 +1,7 @@
|
||||||
* 2020-02-??: Versopm 1.6.0
|
* 2020-02-??: Versopm 1.6.0
|
||||||
* answer_ipv4_address and answer_ipv6_address in reply and response
|
* Issue #432: answer_ipv4_address and answer_ipv6_address in reply
|
||||||
dicts.
|
and response dicts.
|
||||||
|
* Issue #430: Record and guard UDP max payload size with servers.
|
||||||
|
|
||||||
* 2019-12-20: Version 1.6.0-beta.1
|
* 2019-12-20: Version 1.6.0-beta.1
|
||||||
* Migration of build system to cmake. Build now works on Ubuntu,
|
* Migration of build system to cmake. Build now works on Ubuntu,
|
||||||
|
|
26
src/server.c
26
src/server.c
|
@ -102,6 +102,8 @@ struct connection {
|
||||||
struct sockaddr_storage remote_in;
|
struct sockaddr_storage remote_in;
|
||||||
socklen_t addrlen;
|
socklen_t addrlen;
|
||||||
|
|
||||||
|
size_t max_udp_size;
|
||||||
|
|
||||||
connection *next;
|
connection *next;
|
||||||
connection **prev_next;
|
connection **prev_next;
|
||||||
};
|
};
|
||||||
|
@ -326,6 +328,17 @@ getdns_reply(getdns_context *context,
|
||||||
else if (conn->l->transport == GETDNS_TRANSPORT_UDP) {
|
else if (conn->l->transport == GETDNS_TRANSPORT_UDP) {
|
||||||
listener *l = conn->l;
|
listener *l = conn->l;
|
||||||
|
|
||||||
|
if (len > conn->max_udp_size) {
|
||||||
|
_getdns_rr_iter qi_spc, *qi;
|
||||||
|
|
||||||
|
(void)memset(buf + 6, 0, 6);
|
||||||
|
GLDNS_TC_SET(buf);
|
||||||
|
if ((qi = _getdns_rr_iter_init(&qi_spc, buf, len))) {
|
||||||
|
DEBUG_SERVER("Truncating reply to: %d\n",
|
||||||
|
(int)(qi->nxt - buf));
|
||||||
|
len = qi->nxt - buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (conn->l->fd >= 0 && sendto(conn->l->fd, (void *)buf, len, 0,
|
if (conn->l->fd >= 0 && sendto(conn->l->fd, (void *)buf, len, 0,
|
||||||
(struct sockaddr *)&conn->remote_in, conn->addrlen) == -1) {
|
(struct sockaddr *)&conn->remote_in, conn->addrlen) == -1) {
|
||||||
/* TODO: handle _getdns_socketerror_wants_retry() */
|
/* TODO: handle _getdns_socketerror_wants_retry() */
|
||||||
|
@ -545,6 +558,7 @@ static void tcp_accept_cb(void *userarg)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
(void) memset(conn, 0, sizeof(tcp_connection));
|
(void) memset(conn, 0, sizeof(tcp_connection));
|
||||||
|
conn->super.max_udp_size = 65536;
|
||||||
conn->super.l = l;
|
conn->super.l = l;
|
||||||
conn->super.addrlen = sizeof(conn->super.remote_in);
|
conn->super.addrlen = sizeof(conn->super.remote_in);
|
||||||
if ((conn->fd = accept(l->fd, (struct sockaddr *)
|
if ((conn->fd = accept(l->fd, (struct sockaddr *)
|
||||||
|
@ -629,6 +643,7 @@ static void udp_read_cb(void *userarg)
|
||||||
|
|
||||||
conn->l = l;
|
conn->l = l;
|
||||||
conn->addrlen = sizeof(conn->remote_in);
|
conn->addrlen = sizeof(conn->remote_in);
|
||||||
|
conn->max_udp_size = 512;
|
||||||
if ((len = recvfrom(l->fd, (void *)buf, sizeof(buf), 0,
|
if ((len = recvfrom(l->fd, (void *)buf, sizeof(buf), 0,
|
||||||
(struct sockaddr *)&conn->remote_in, &conn->addrlen)) == -1) {
|
(struct sockaddr *)&conn->remote_in, &conn->addrlen)) == -1) {
|
||||||
if ( _getdns_socketerror_wants_retry() &&
|
if ( _getdns_socketerror_wants_retry() &&
|
||||||
|
@ -713,6 +728,8 @@ static void udp_read_cb(void *userarg)
|
||||||
; /* FROMERR on input, ignore */
|
; /* FROMERR on input, ignore */
|
||||||
|
|
||||||
else {
|
else {
|
||||||
|
uint32_t max_udp_size = 512;
|
||||||
|
|
||||||
/* Insert connection */
|
/* Insert connection */
|
||||||
conn->super.key = conn;
|
conn->super.key = conn;
|
||||||
if (!_getdns_rbtree_insert(
|
if (!_getdns_rbtree_insert(
|
||||||
|
@ -723,6 +740,15 @@ static void udp_read_cb(void *userarg)
|
||||||
}
|
}
|
||||||
DEBUG_SERVER("[connection add] count: %d\n",
|
DEBUG_SERVER("[connection add] count: %d\n",
|
||||||
(int)l->set->connections_set.count);
|
(int)l->set->connections_set.count);
|
||||||
|
|
||||||
|
if (!getdns_dict_get_int(request_dict,
|
||||||
|
"/additional/0/udp_payload_size", &max_udp_size))
|
||||||
|
conn->max_udp_size = max_udp_size;
|
||||||
|
|
||||||
|
else if (!getdns_dict_get_int(request_dict,
|
||||||
|
"/additional/1/udp_payload_size", &max_udp_size))
|
||||||
|
conn->max_udp_size = max_udp_size;
|
||||||
|
|
||||||
if ((conn->next = l->connections))
|
if ((conn->next = l->connections))
|
||||||
conn->next->prev_next = &conn->next;
|
conn->next->prev_next = &conn->next;
|
||||||
conn->prev_next = &l->connections;
|
conn->prev_next = &l->connections;
|
||||||
|
|
Loading…
Reference in New Issue