@@ -52,17 +52,32 @@ static const char *str_family(int family)
5252 }
5353}
5454
55- static int socket_timeout_set (int fd , int type )
55+ static int set_recv_socket_timeout (int fd , int timeout_ms )
5656{
5757 int err ;
58- uint32_t timeout_ms ;
5958
60- if (type == SOCK_STREAM ) {
61- timeout_ms = CONFIG_DOWNLOAD_CLIENT_TCP_SOCK_TIMEO_MS ;
62- } else {
63- timeout_ms = CONFIG_DOWNLOAD_CLIENT_UDP_SOCK_TIMEO_MS ;
59+ if (timeout_ms <= 0 ) {
60+ return 0 ;
61+ }
62+
63+ struct timeval timeo = {
64+ .tv_sec = (timeout_ms / 1000 ),
65+ .tv_usec = (timeout_ms % 1000 ) * 1000 ,
66+ };
67+
68+ err = setsockopt (fd , SOL_SOCKET , SO_RCVTIMEO , & timeo , sizeof (timeo ));
69+ if (err ) {
70+ LOG_WRN ("Failed to set socket timeout, errno %d" , errno );
71+ return -1 ;
6472 }
6573
74+ return 0 ;
75+ }
76+
77+ static int set_snd_socket_timeout (int fd , int timeout_ms )
78+ {
79+ int err ;
80+
6681 if (timeout_ms <= 0 ) {
6782 return 0 ;
6883 }
@@ -72,15 +87,10 @@ static int socket_timeout_set(int fd, int type)
7287 .tv_usec = (timeout_ms % 1000 ) * 1000 ,
7388 };
7489
75- #if defined(CONFIG_POSIX_API )
76- LOG_INF ("Configuring socket timeout (%d s)" , (int32_t )timeo .tv_sec );
77- #else
78- LOG_INF ("Configuring socket timeout (%lld s)" , timeo .tv_sec );
79- #endif
80- err = setsockopt (fd , SOL_SOCKET , SO_RCVTIMEO , & timeo , sizeof (timeo ));
90+ err = setsockopt (fd , SOL_SOCKET , SO_SNDTIMEO , & timeo , sizeof (timeo ));
8191 if (err ) {
8292 LOG_WRN ("Failed to set socket timeout, errno %d" , errno );
83- return - errno ;
93+ return -1 ;
8494 }
8595
8696 return 0 ;
@@ -296,12 +306,6 @@ static int client_connect(struct download_client *dl)
296306 }
297307 }
298308
299- /* Set socket timeout, if configured */
300- err = socket_timeout_set (dl -> fd , type );
301- if (err ) {
302- goto cleanup ;
303- }
304-
305309 LOG_INF ("Connecting to %s" , log_strdup (dl -> host ));
306310 LOG_DBG ("fd %d, addrlen %d, fam %s, port %d" ,
307311 dl -> fd , addrlen , str_family (dl -> remote_addr .sa_family ), port );
@@ -322,11 +326,17 @@ static int client_connect(struct download_client *dl)
322326 return err ;
323327}
324328
325- int socket_send (const struct download_client * client , size_t len )
329+ int socket_send (const struct download_client * client , size_t len , int timeout )
326330{
331+ int err ;
327332 int sent ;
328333 size_t off = 0 ;
329334
335+ err = set_snd_socket_timeout (client -> fd , timeout );
336+ if (err ) {
337+ return - errno ;
338+ }
339+
330340 while (len ) {
331341 sent = send (client -> fd , client -> buf + off , len , 0 );
332342 if (sent < 0 ) {
@@ -403,6 +413,34 @@ static int reconnect(struct download_client *dl)
403413 return 0 ;
404414}
405415
416+ static size_t socket_recv (struct download_client * dl )
417+ {
418+ int err , timeout = 0 ;
419+
420+ switch (dl -> proto ) {
421+ case IPPROTO_TCP :
422+ case IPPROTO_TLS_1_2 :
423+ timeout = CONFIG_DOWNLOAD_CLIENT_TCP_SOCK_TIMEO_MS ;
424+ break ;
425+ case IPPROTO_UDP :
426+ case IPPROTO_DTLS_1_2 :
427+ if (IS_ENABLED (CONFIG_COAP )) {
428+ timeout = CONFIG_DOWNLOAD_CLIENT_UDP_SOCK_TIMEO_MS ;
429+ break ;
430+ }
431+ default :
432+ LOG_ERR ("unhandled proto" );
433+ return -1 ;
434+ }
435+
436+ err = set_recv_socket_timeout (dl -> fd , timeout );
437+ if (err ) {
438+ return -1 ;
439+ }
440+
441+ return recv (dl -> fd , dl -> buf + dl -> offset , sizeof (dl -> buf ) - dl -> offset , 0 );
442+ }
443+
406444void download_thread (void * client , void * a , void * b )
407445{
408446 int rc = 0 ;
@@ -426,8 +464,7 @@ void download_thread(void *client, void *a, void *b)
426464 LOG_DBG ("Receiving up to %d bytes at %p..." ,
427465 (sizeof (dl -> buf ) - dl -> offset ), (dl -> buf + dl -> offset ));
428466
429- len = recv (dl -> fd , dl -> buf + dl -> offset ,
430- sizeof (dl -> buf ) - dl -> offset , 0 );
467+ len = socket_recv (dl );
431468
432469 if ((len == 0 ) || (len == -1 )) {
433470 /* We just had an unexpected socket error or closure */
0 commit comments