@@ -1399,12 +1399,18 @@ nc_connect_unix(const char *address, struct ly_ctx *ctx)
13991399 return NULL ;
14001400}
14011401
1402- /*
1403- Helper for a non-blocking connect (which is required because of the locking
1404- concept for e.g. call home settings). For more details see nc_sock_connect().
1402+ /**
1403+ * @brief Try to connect a socket, optionally a pending one from a previous attempt.
1404+ *
1405+ * @param[in] timeout_ms Timeout in ms to wait for the connection to be fully established, -1 to block.
1406+ * @param[in,out] sock_pending Optional previously created socked that was not fully connected yet. If provided and
1407+ * connected, is set to -1.
1408+ * @param[in] res Addrinfo resource to use when creating a new socket.
1409+ * @param[in] ka Keepalives to set.
1410+ * @return Connected socket or -1 on error.
14051411 */
14061412static int
1407- _non_blocking_connect (int timeout , int * sock_pending , struct addrinfo * res , struct nc_keepalives * ka )
1413+ sock_connect (int timeout_ms , int * sock_pending , struct addrinfo * res , struct nc_keepalives * ka )
14081414{
14091415 int flags , ret , error ;
14101416 int sock = -1 ;
@@ -1453,20 +1459,23 @@ _non_blocking_connect(int timeout, int *sock_pending, struct addrinfo *res, stru
14531459 }
14541460 }
14551461 }
1456- ts .tv_sec = timeout ;
1457- ts .tv_usec = 0 ;
14581462
14591463 FD_ZERO (& wset );
14601464 FD_SET (sock , & wset );
14611465
1462- if ((ret = select (sock + 1 , NULL , & wset , NULL , (timeout != -1 ) ? & ts : NULL )) < 0 ) {
1466+ /* wait for some data on the socket */
1467+ if (timeout_ms != -1 ) {
1468+ ts .tv_sec = timeout_ms / 1000 ;
1469+ ts .tv_usec = (timeout_ms % 1000 ) * 1000 ;
1470+ }
1471+ if ((ret = select (sock + 1 , NULL , & wset , NULL , (timeout_ms != -1 ) ? & ts : NULL )) < 0 ) {
14631472 ERR (NULL , "select() failed (%s)." , strerror (errno ));
14641473 goto cleanup ;
14651474 }
14661475
14671476 if (ret == 0 ) {
14681477 /* there was a timeout */
1469- VRB (NULL , "Timed out after %ds (%s)." , timeout , strerror (errno ));
1478+ VRB (NULL , "Timed out after %d ms (%s)." , timeout_ms , strerror (errno ));
14701479 if (sock_pending ) {
14711480 /* no sock-close, we'll try it again */
14721481 * sock_pending = sock ;
@@ -1494,6 +1503,10 @@ _non_blocking_connect(int timeout, int *sock_pending, struct addrinfo *res, stru
14941503 goto cleanup ;
14951504 }
14961505
1506+ /* connected */
1507+ if (sock_pending ) {
1508+ * sock_pending = -1 ;
1509+ }
14971510 return sock ;
14981511
14991512cleanup :
@@ -1504,24 +1517,16 @@ _non_blocking_connect(int timeout, int *sock_pending, struct addrinfo *res, stru
15041517 return -1 ;
15051518}
15061519
1507- /* A given timeout value limits the time how long the function blocks. If it has to block
1508- only for some seconds, a socket connection might not yet have been fully established.
1509- Therefore the active (pending) socket will be stored in *sock_pending, but the return
1510- value will be -1. In such a case a subsequent invokation is required, by providing the
1511- stored sock_pending, again.
1512- In general, if this function returns -1, when a timeout has been given, this function
1513- has to be invoked, until it returns a valid socket.
1514- */
15151520int
1516- nc_sock_connect (const char * host , uint16_t port , int timeout , struct nc_keepalives * ka , int * sock_pending , char * * ip_host )
1521+ nc_sock_connect (const char * host , uint16_t port , int timeout_ms , struct nc_keepalives * ka , int * sock_pending , char * * ip_host )
15171522{
15181523 int i , opt ;
15191524 int sock = sock_pending ? * sock_pending : -1 ;
15201525 struct addrinfo hints , * res_list = NULL , * res ;
15211526 char * buf , port_s [6 ]; /* length of string representation of short int */
15221527 void * addr ;
15231528
1524- DBG (NULL , "nc_sock_connect(%s, %u, %d, %d)" , host , port , timeout , sock );
1529+ DBG (NULL , "nc_sock_connect(%s, %u, %d, %d)" , host , port , timeout_ms , sock );
15251530
15261531 /* no pending socket */
15271532 if (sock == -1 ) {
@@ -1538,7 +1543,7 @@ nc_sock_connect(const char *host, uint16_t port, int timeout, struct nc_keepaliv
15381543 }
15391544
15401545 for (res = res_list ; res != NULL ; res = res -> ai_next ) {
1541- sock = _non_blocking_connect ( timeout , sock_pending , res , ka );
1546+ sock = sock_connect ( timeout_ms , sock_pending , res , ka );
15421547 if (sock == -1 ) {
15431548 if (!sock_pending || (* sock_pending == -1 )) {
15441549 /* try the next resource */
@@ -1582,7 +1587,7 @@ nc_sock_connect(const char *host, uint16_t port, int timeout, struct nc_keepaliv
15821587 } else {
15831588 /* try to get a connection with the pending socket */
15841589 assert (sock_pending );
1585- sock = _non_blocking_connect ( timeout , sock_pending , NULL , ka );
1590+ sock = sock_connect ( timeout_ms , sock_pending , NULL , ka );
15861591 }
15871592
15881593 return sock ;
0 commit comments