net: tcp: add timeout wait in net_context_connect
If the parameter "timeout" is set in net_context_connect(), the assumption by the user is that the function would wait for SYNACK to be received before returning to the caller. Currently this is not the case. The timeout parameter is handed off to net_l2_offload_ip_connect() if CONFIG_NET_L2_OFFLOAD_IP is defined but never handled in a normal call. To implement the timeout, let's use a semaphore to wait for tcp_synack_received() to get a SYNACK before returning from net_context_connect(). Change-Id: I7565550ed5545e6410b2d99c429367c1fb539970 Signed-off-by: Michael Scott <michael.scott@linaro.org>
This commit is contained in:
parent
eb9055c019
commit
72e013a7ba
4 changed files with 18 additions and 1 deletions
|
@ -477,6 +477,7 @@ typedef void (*net_context_connect_cb_t)(struct net_context *context,
|
|||
* @return 0 on success.
|
||||
* @return -EINVAL if an invalid parameter is passed as an argument.
|
||||
* @return -ENOTSUP if the operation is not supported or implemented.
|
||||
* @return -ETIMEDOUT if the connect operation times out.
|
||||
*/
|
||||
int net_context_connect(struct net_context *context,
|
||||
const struct sockaddr *addr,
|
||||
|
|
|
@ -928,6 +928,8 @@ static enum net_verdict tcp_synack_received(struct net_conn *conn,
|
|||
net_context_set_state(context, NET_CONTEXT_CONNECTED);
|
||||
|
||||
send_ack(context, raddr);
|
||||
|
||||
k_sem_give(&context->tcp->connect_wait);
|
||||
}
|
||||
|
||||
return NET_DROP;
|
||||
|
@ -950,6 +952,9 @@ int net_context_connect(struct net_context *context,
|
|||
|
||||
NET_ASSERT(addr);
|
||||
NET_ASSERT(PART_OF_ARRAY(contexts, context));
|
||||
#if defined(CONFIG_NET_TCP)
|
||||
NET_ASSERT(context->tcp);
|
||||
#endif
|
||||
|
||||
if (!net_context_is_used(context)) {
|
||||
return -ENOENT;
|
||||
|
@ -1104,12 +1109,16 @@ int net_context_connect(struct net_context *context,
|
|||
|
||||
net_context_set_state(context, NET_CONTEXT_CONNECTING);
|
||||
|
||||
/* FIXME - set timer to wait for SYN-ACK */
|
||||
send_syn(context, addr);
|
||||
|
||||
if (cb) {
|
||||
cb(context, user_data);
|
||||
}
|
||||
|
||||
/* in tcp_synack_received() we give back this semaphore */
|
||||
if (k_sem_take(&context->tcp->connect_wait, timeout)) {
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -152,6 +152,7 @@ struct net_tcp *net_tcp_alloc(struct net_context *context)
|
|||
tcp_context[i].accept_cb = NULL;
|
||||
|
||||
k_timer_init(&tcp_context[i].retry_timer, tcp_retry_expired, NULL);
|
||||
k_sem_init(&tcp_context[i].connect_wait, 0, UINT_MAX);
|
||||
|
||||
return &tcp_context[i];
|
||||
}
|
||||
|
@ -167,6 +168,7 @@ int net_tcp_release(struct net_tcp *tcp)
|
|||
k_delayed_work_cancel(&tcp->fin_timer);
|
||||
k_delayed_work_cancel(&tcp->ack_timer);
|
||||
k_timer_stop(&tcp->retry_timer);
|
||||
k_sem_reset(&tcp->connect_wait);
|
||||
|
||||
net_tcp_set_state(tcp, NET_TCP_CLOSED);
|
||||
tcp->context = NULL;
|
||||
|
|
|
@ -138,6 +138,11 @@ struct net_tcp {
|
|||
* established.
|
||||
*/
|
||||
net_tcp_accept_cb_t accept_cb;
|
||||
|
||||
/**
|
||||
* Semaphore to signal TCP connection completion
|
||||
*/
|
||||
struct k_sem connect_wait;
|
||||
};
|
||||
|
||||
static inline bool net_tcp_is_used(struct net_tcp *tcp)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue