Skip to content

Commit a41f625

Browse files
jukkarfabiobaltieri
authored andcommitted
net: tcp: Make sure that connection failure is propagated to app
It is possible that TCP connect() will fail if for example network interface does not have IP address set. In this case we close the connection during net_tcp_connect() but do not set the return code properly. This looks in the application like the connection succeeded even if it was not. As the tcp_in() call in net_tcp_connect() might close the connection, we just take extra ref count while calling tcp_in(). Otherwise we might access already freed connection. Before the fix: net_tcp_connect: context: 0x80757c0, local: 0.0.0.0, remote: 192.0.2.2 net_tcp_connect: conn: 0x8087320 src: 0.0.0.0, dst: 192.0.2.2 tcp_in: [LISTEN Seq=1604170158 Ack=0] tcp_conn_close_debug: conn: 0x8087320 closed by TCP stack (tcp_in():3626) tcp_conn_close_debug: LISTEN->CLOSED tcp_conn_unref: conn: 0x8087320, ref_count=1 net_tcp_connect: conn: 0x8087320, ret=0 After the fix: net_tcp_connect: context: 0x80757c0, local: 0.0.0.0, remote: 192.0.2.2 net_tcp_connect: conn: 0x8087320 src: 0.0.0.0, dst: 192.0.2.2 tcp_conn_ref: conn: 0x8087320, ref_count: 2 tcp_in: [LISTEN Seq=1604170158 Ack=0] tcp_conn_close_debug: conn: 0x8087320 closed by TCP stack (tcp_in():3626) tcp_conn_close_debug: LISTEN->CLOSED tcp_conn_unref: conn: 0x8087320, ref_count=2 net_tcp: tcp_conn_unref: conn: 0x8087320, ref_count=1 net_tcp: net_tcp_connect: conn: 0x8087320, ret=-128 Signed-off-by: Jukka Rissanen <[email protected]>
1 parent 57a8a7c commit a41f625

File tree

1 file changed

+14
-5
lines changed

1 file changed

+14
-5
lines changed

subsys/net/ip/tcp.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3948,16 +3948,21 @@ int net_tcp_connect(struct net_context *context,
39483948
* a TCP connection to be established
39493949
*/
39503950
conn->in_connect = !IS_ENABLED(CONFIG_NET_TEST_PROTOCOL);
3951+
3952+
/* The ref will make sure that if the connection is closed in tcp_in(),
3953+
* we do not access already freed connection.
3954+
*/
3955+
tcp_conn_ref(conn);
39513956
(void)tcp_in(conn, NULL);
39523957

39533958
if (!IS_ENABLED(CONFIG_NET_TEST_PROTOCOL)) {
39543959
if (conn->state == TCP_UNUSED || conn->state == TCP_CLOSED) {
3955-
ret = -errno;
3956-
goto out;
3960+
ret = -ENOTCONN;
3961+
goto out_unref;
39573962
} else if ((K_TIMEOUT_EQ(timeout, K_NO_WAIT)) &&
39583963
conn->state != TCP_ESTABLISHED) {
39593964
ret = -EINPROGRESS;
3960-
goto out;
3965+
goto out_unref;
39613966
} else if (k_sem_take(&conn->connect_sem, timeout) != 0 &&
39623967
conn->state != TCP_ESTABLISHED) {
39633968
if (conn->in_connect) {
@@ -3966,11 +3971,15 @@ int net_tcp_connect(struct net_context *context,
39663971
}
39673972

39683973
ret = -ETIMEDOUT;
3969-
goto out;
3974+
goto out_unref;
39703975
}
39713976
conn->in_connect = false;
39723977
}
3973-
out:
3978+
3979+
out_unref:
3980+
tcp_conn_unref(conn);
3981+
3982+
out:
39743983
NET_DBG("conn: %p, ret=%d", conn, ret);
39753984

39763985
return ret;

0 commit comments

Comments
 (0)