Commit 7291e803 authored by Grigorii Demidov's avatar Grigorii Demidov Committed by Petr Špaček

daemon: check source in udp answer

parent 82a7203e
......@@ -160,6 +160,12 @@ void udp_recv(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf,
if (addr->sa_family == AF_UNSPEC) {
return;
}
if (s->outgoing) {
assert(s->peer.ip.sa_family != AF_UNSPEC);
if (kr_sockaddr_cmp(&s->peer.ip, addr) != 0) {
return;
}
}
knot_pkt_t *query = knot_pkt_new(buf->base, nread, &worker->pkt_pool);
if (query) {
query->max_size = KNOT_WIRE_MAX_PKTSIZE;
......
......@@ -1384,8 +1384,15 @@ static uv_handle_t *retransmit(struct qr_task *task)
return ret;
}
ret = ioreq_spawn(task, SOCK_DGRAM, choice->sin6_family);
if (ret &&
qr_task_send(task, ret, (struct sockaddr *)choice,
if (!ret) {
return ret;
}
struct sockaddr *addr = (struct sockaddr *)choice;
struct session *session = ret->data;
assert (session->peer.ip.sa_family == AF_UNSPEC);
session->outgoing = true;
memcpy(&session->peer, addr, sizeof(session->peer));
if (qr_task_send(task, ret, (struct sockaddr *)choice,
task->pktbuf) == 0) {
task->addrlist_turn = (task->addrlist_turn + 1) %
task->addrlist_count; /* Round robin */
......
......@@ -365,6 +365,33 @@ int kr_sockaddr_len(const struct sockaddr *addr)
}
}
int kr_sockaddr_cmp(const struct sockaddr *left, const struct sockaddr *right)
{
if (!left || !right) {
return kr_error(EINVAL);
}
if (left->sa_family != right->sa_family) {
return kr_error(EFAULT);
}
if (left->sa_family == AF_INET) {
struct sockaddr_in *left_in = (struct sockaddr_in *)left;
struct sockaddr_in *right_in = (struct sockaddr_in *)right;
if (left_in->sin_addr.s_addr != right_in->sin_addr.s_addr) {
return kr_error(EFAULT);
}
} else if (left->sa_family == AF_INET6) {
struct sockaddr_in6 *left_in6 = (struct sockaddr_in6 *)left;
struct sockaddr_in6 *right_in6 = (struct sockaddr_in6 *)right;
if (memcmp(&left_in6->sin6_addr, &right_in6->sin6_addr,
sizeof(struct in6_addr)) != 0) {
return kr_error(EFAULT);
}
} else {
return kr_error(ENOENT);
}
return kr_ok();
}
uint16_t kr_inaddr_port(const struct sockaddr *addr)
{
if (!addr) {
......
......@@ -233,6 +233,11 @@ int kr_inaddr_len(const struct sockaddr *addr);
/** Sockaddr length for given family, i.e. sizeof(struct sockaddr_in*). */
KR_EXPORT KR_PURE
int kr_sockaddr_len(const struct sockaddr *addr);
/** Compare two given sockaddr.
* return 0 - addresses are equal, error code otherwise.
*/
KR_EXPORT KR_PURE
int kr_sockaddr_cmp(const struct sockaddr *left, const struct sockaddr *right);
/** Port. */
KR_EXPORT KR_PURE
uint16_t kr_inaddr_port(const struct sockaddr *addr);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment