net: conn: Check duplicate UDP/TCP connection handlers
When a new UDP or TCP connection handler is to be registered, we need to check if identical handler has already been created. If a duplicate is found, the registering call will return -EALREADY. The earlier code did not check this but allowed two identical handlers to be created. The latter handler was never called in this case. Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
parent
c77460da53
commit
43b37cef31
1 changed files with 110 additions and 0 deletions
|
@ -412,6 +412,108 @@ void prepare_register_debug_print(char *dst, int dst_len,
|
|||
}
|
||||
#endif /* CONFIG_NET_DEBUG_CONN */
|
||||
|
||||
/* Check if we already have identical connection handler installed. */
|
||||
static int find_conn_handler(enum net_ip_protocol proto,
|
||||
const struct sockaddr *remote_addr,
|
||||
const struct sockaddr *local_addr,
|
||||
u16_t remote_port,
|
||||
u16_t local_port)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_NET_MAX_CONN; i++) {
|
||||
if (!(conns[i].flags & NET_CONN_IN_USE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (conns[i].proto != proto) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (remote_addr) {
|
||||
if (!(conns[i].flags & NET_CONN_REMOTE_ADDR_SET)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NET_IPV6)
|
||||
if (remote_addr->family == AF_INET6) {
|
||||
if (!net_ipv6_addr_cmp(
|
||||
&net_sin6(remote_addr)->sin6_addr,
|
||||
&net_sin6(&conns[i].remote_addr)->
|
||||
sin6_addr)) {
|
||||
continue;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
#if defined(CONFIG_NET_IPV4)
|
||||
if (remote_addr->family == AF_INET) {
|
||||
if (!net_ipv4_addr_cmp(
|
||||
&net_sin(remote_addr)->sin_addr,
|
||||
&net_sin(&conns[i].remote_addr)->
|
||||
sin_addr)) {
|
||||
continue;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (conns[i].flags & NET_CONN_REMOTE_ADDR_SET) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (local_addr) {
|
||||
if (!(conns[i].flags & NET_CONN_LOCAL_ADDR_SET)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NET_IPV6)
|
||||
if (local_addr->family == AF_INET6) {
|
||||
if (!net_ipv6_addr_cmp(
|
||||
&net_sin6(local_addr)->sin6_addr,
|
||||
&net_sin6(&conns[i].local_addr)->
|
||||
sin6_addr)) {
|
||||
continue;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
#if defined(CONFIG_NET_IPV4)
|
||||
if (local_addr->family == AF_INET) {
|
||||
if (!net_ipv4_addr_cmp(
|
||||
&net_sin(local_addr)->sin_addr,
|
||||
&net_sin(&conns[i].local_addr)->
|
||||
sin_addr)) {
|
||||
continue;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (conns[i].flags & NET_CONN_LOCAL_ADDR_SET) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (net_sin(&conns[i].remote_addr)->sin_port !=
|
||||
htons(remote_port)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (net_sin(&conns[i].local_addr)->sin_port !=
|
||||
htons(local_port)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
int net_conn_register(enum net_ip_protocol proto,
|
||||
const struct sockaddr *remote_addr,
|
||||
const struct sockaddr *local_addr,
|
||||
|
@ -424,6 +526,14 @@ int net_conn_register(enum net_ip_protocol proto,
|
|||
int i;
|
||||
u8_t rank = 0;
|
||||
|
||||
i = find_conn_handler(proto, remote_addr, local_addr, remote_port,
|
||||
local_port);
|
||||
if (i != -ENOENT) {
|
||||
NET_ERR("Identical connection handler %p already found.",
|
||||
&conns[i]);
|
||||
return -EALREADY;
|
||||
}
|
||||
|
||||
for (i = 0; i < CONFIG_NET_MAX_CONN; i++) {
|
||||
if (conns[i].flags & NET_CONN_IN_USE) {
|
||||
continue;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue