@@ -116,6 +116,7 @@ namespace {
116116 constexpr std::size_t CLIENT_CHALLENGE_BYTE_COUNT = 16 ;
117117 constexpr std::size_t CLIENT_SECRET_BYTE_COUNT = 16 ;
118118 constexpr int SOCKET_TIMEOUT_MILLISECONDS = 5000 ;
119+ constexpr int PIN_ENTRY_SOCKET_TIMEOUT_MILLISECONDS = 90000 ;
119120 constexpr uint16_t DEFAULT_SERVERINFO_HTTP_PORT = 47989 ;
120121 constexpr uint16_t FALLBACK_SERVERINFO_HTTP_PORT = 47984 ;
121122 constexpr uint16_t DEFAULT_SERVERINFO_HTTPS_PORT = 47990 ;
@@ -217,7 +218,7 @@ namespace {
217218
218219 bool is_timeout_error (int errorCode) {
219220#if defined(NXDK) || !defined(_WIN32)
220- return errorCode == ETIMEDOUT ;
221+ return errorCode == ETIMEDOUT || errorCode == EWOULDBLOCK || errorCode == EAGAIN ;
221222#else
222223 return errorCode == WSAETIMEDOUT ;
223224#endif
@@ -249,18 +250,18 @@ namespace {
249250 return true ;
250251 }
251252
252- void set_socket_timeouts (SOCKET socketHandle) {
253+ void set_socket_timeouts (SOCKET socketHandle, int timeoutMilliseconds ) {
253254#if defined(NXDK) || !defined(_WIN32)
254255 timeval timeout {
255- SOCKET_TIMEOUT_MILLISECONDS / 1000 ,
256- (SOCKET_TIMEOUT_MILLISECONDS % 1000 ) * 1000 ,
256+ timeoutMilliseconds / 1000 ,
257+ (timeoutMilliseconds % 1000 ) * 1000 ,
257258 };
258259 setsockopt (socketHandle, SOL_SOCKET , SO_RCVTIMEO , reinterpret_cast <const char *>(&timeout), sizeof (timeout));
259260 setsockopt (socketHandle, SOL_SOCKET , SO_SNDTIMEO , reinterpret_cast <const char *>(&timeout), sizeof (timeout));
260261#else
261- const DWORD timeoutMilliseconds = SOCKET_TIMEOUT_MILLISECONDS ;
262- setsockopt (socketHandle, SOL_SOCKET , SO_RCVTIMEO , reinterpret_cast <const char *>(&timeoutMilliseconds ), sizeof (timeoutMilliseconds ));
263- setsockopt (socketHandle, SOL_SOCKET , SO_SNDTIMEO , reinterpret_cast <const char *>(&timeoutMilliseconds ), sizeof (timeoutMilliseconds ));
262+ const DWORD platformTimeoutMilliseconds = static_cast < DWORD >(timeoutMilliseconds) ;
263+ setsockopt (socketHandle, SOL_SOCKET , SO_RCVTIMEO , reinterpret_cast <const char *>(&platformTimeoutMilliseconds ), sizeof (platformTimeoutMilliseconds ));
264+ setsockopt (socketHandle, SOL_SOCKET , SO_SNDTIMEO , reinterpret_cast <const char *>(&platformTimeoutMilliseconds ), sizeof (platformTimeoutMilliseconds ));
264265#endif
265266 }
266267
@@ -351,7 +352,8 @@ namespace {
351352 std::string_view expectedTlsCertificatePem,
352353 HttpResponse *response,
353354 std::string *errorMessage,
354- const std::atomic<bool > *cancelRequested = nullptr
355+ const std::atomic<bool > *cancelRequested = nullptr ,
356+ int socketIoTimeoutMilliseconds = SOCKET_TIMEOUT_MILLISECONDS
355357 );
356358
357359 std::string summarize_http_payload_preview (std::string_view text) {
@@ -1496,18 +1498,25 @@ namespace {
14961498 return true ;
14971499 }
14981500
1499- bool finalize_connected_socket (SOCKET socketHandle, std::string *errorMessage) {
1501+ bool finalize_connected_socket (SOCKET socketHandle, int socketIoTimeoutMilliseconds, std::string *errorMessage) {
15001502 trace_pairing_phase (" restoring blocking mode after connect" );
15011503 if (!set_socket_non_blocking (socketHandle, false , errorMessage)) {
15021504 return false ;
15031505 }
15041506
1505- set_socket_timeouts (socketHandle);
1507+ set_socket_timeouts (socketHandle, socketIoTimeoutMilliseconds );
15061508 trace_pairing_phase (" socket connected" );
15071509 return true ;
15081510 }
15091511
1510- bool connect_socket (const std::string &address, uint16_t port, SocketGuard *socketGuard, std::string *errorMessage, const std::atomic<bool > *cancelRequested = nullptr ) {
1512+ bool connect_socket (
1513+ const std::string &address,
1514+ uint16_t port,
1515+ SocketGuard *socketGuard,
1516+ int socketIoTimeoutMilliseconds,
1517+ std::string *errorMessage,
1518+ const std::atomic<bool > *cancelRequested = nullptr
1519+ ) {
15111520 if (socketGuard == nullptr ) {
15121521 return append_error (errorMessage, " Internal pairing error while preparing the host connection" );
15131522 }
@@ -1547,7 +1556,7 @@ namespace {
15471556 }
15481557 }
15491558
1550- return finalize_connected_socket (socketGuard->handle , errorMessage);
1559+ return finalize_connected_socket (socketGuard->handle , socketIoTimeoutMilliseconds, errorMessage);
15511560 }
15521561
15531562 bool recv_all_plain (SOCKET socketHandle, std::string *response, std::string *errorMessage, const std::atomic<bool > *cancelRequested = nullptr ) {
@@ -1855,7 +1864,8 @@ namespace {
18551864 std::string_view expectedTlsCertificatePem,
18561865 HttpResponse *response,
18571866 std::string *errorMessage,
1858- const std::atomic<bool > *cancelRequested
1867+ const std::atomic<bool > *cancelRequested,
1868+ int socketIoTimeoutMilliseconds
18591869 ) {
18601870 if (pairing_cancel_requested (cancelRequested)) {
18611871 return append_cancelled_pairing_error (errorMessage);
@@ -1869,6 +1879,7 @@ namespace {
18691879 useTls,
18701880 tlsClientIdentity,
18711881 std::string (expectedTlsCertificatePem),
1882+ socketIoTimeoutMilliseconds,
18721883 };
18731884 network::testing::HostPairingHttpTestResponse testResponse {};
18741885 if (std::string testError; !testHandler (testRequest, &testResponse, &testError, cancelRequested)) {
@@ -1891,7 +1902,7 @@ namespace {
18911902
18921903 SocketGuard socketGuard;
18931904 trace_pairing_phase (" http_get: connect_socket" );
1894- if (!connect_socket (address, port, &socketGuard, errorMessage, cancelRequested)) {
1905+ if (!connect_socket (address, port, &socketGuard, socketIoTimeoutMilliseconds, errorMessage, cancelRequested)) {
18951906 return false ;
18961907 }
18971908
@@ -2149,12 +2160,18 @@ namespace {
21492160 return true ;
21502161 }
21512162
2152- bool execute_pairing_phase_request (PairingSessionState *session, const std::string &path, bool useTls, std::string_view expectedTlsCertificatePem = {}) {
2163+ bool execute_pairing_phase_request (
2164+ PairingSessionState *session,
2165+ const std::string &path,
2166+ bool useTls,
2167+ std::string_view expectedTlsCertificatePem = {},
2168+ int socketIoTimeoutMilliseconds = SOCKET_TIMEOUT_MILLISECONDS
2169+ ) {
21532170 if (session == nullptr ) {
21542171 return false ;
21552172 }
21562173
2157- if (!http_get (session->request .address , useTls ? session->serverInfo .httpsPort : session->serverInfo .httpPort , path, useTls, useTls ? &session->request .identity : nullptr , expectedTlsCertificatePem, &session->response , &session->errorMessage , session->cancelRequested )) {
2174+ if (!http_get (session->request .address , useTls ? session->serverInfo .httpsPort : session->serverInfo .httpPort , path, useTls, useTls ? &session->request .identity : nullptr , expectedTlsCertificatePem, &session->response , &session->errorMessage , session->cancelRequested , socketIoTimeoutMilliseconds )) {
21582175 return false ;
21592176 }
21602177 return parse_pairing_tag (session->response , " paired" , &session->phaseValue , &session->errorMessage );
@@ -2187,7 +2204,7 @@ namespace {
21872204
21882205 const std::string phasePath = " /pair?uniqueid=" + session->uniqueId + " &uuid=" + session->requestUuid + " &devicename=" + session->deviceName + " &updateState=1&phrase=getservercert&salt=" + session->saltHex + " &clientcert=" + certHex;
21892206 trace_pairing_phase (" phase 1 getservercert request" );
2190- if (!execute_pairing_phase_request (session, phasePath, false )) {
2207+ if (!execute_pairing_phase_request (session, phasePath, false , {}, PIN_ENTRY_SOCKET_TIMEOUT_MILLISECONDS )) {
21912208 return false ;
21922209 }
21932210 if (session->phaseValue != " 1" ) {
0 commit comments