@@ -324,7 +324,27 @@ private function handleSocks5(ConnectionInterface $stream, $host, $port, StreamR
324324 throw new Exception ('Invalid SOCKS response ' );
325325 }
326326 if ($ data ['status ' ] !== 0x00 ) {
327- throw new RuntimeException ('Proxy refused connection with SOCKS error code ' . sprintf ('0x%02X ' , $ data ['status ' ]) . ' (ECONNREFUSED) ' , defined ('SOCKET_ECONNREFUSED ' ) ? SOCKET_ECONNREFUSED : 111 );
327+ // map limited list of SOCKS error codes to common socket error conditions
328+ // @link https://tools.ietf.org/html/rfc1928#section-6
329+ if ($ data ['status ' ] === Server::ERROR_GENERAL ) {
330+ throw new RuntimeException ('SOCKS server reported a general server failure (ECONNREFUSED) ' , defined ('SOCKET_ECONNREFUSED ' ) ? SOCKET_ECONNREFUSED : 111 );
331+ } elseif ($ data ['status ' ] === Server::ERROR_NOT_ALLOWED_BY_RULESET ) {
332+ throw new RuntimeException ('SOCKS server reported connection is not allowed by ruleset (EACCES) ' , defined ('SOCKET_EACCES ' ) ? SOCKET_EACCES : 13 );
333+ } elseif ($ data ['status ' ] === Server::ERROR_NETWORK_UNREACHABLE ) {
334+ throw new RuntimeException ('SOCKS server reported network unreachable (ENETUNREACH) ' , defined ('SOCKET_ENETUNREACH ' ) ? SOCKET_ENETUNREACH : 101 );
335+ } elseif ($ data ['status ' ] === Server::ERROR_HOST_UNREACHABLE ) {
336+ throw new RuntimeException ('SOCKS server reported host unreachable (EHOSTUNREACH) ' , defined ('SOCKET_EHOSTUNREACH ' ) ? SOCKET_EHOSTUNREACH : 113 );
337+ } elseif ($ data ['status ' ] === Server::ERROR_CONNECTION_REFUSED ) {
338+ throw new RuntimeException ('SOCKS server reported connection refused (ECONNREFUSED) ' , defined ('SOCKET_ECONNREFUSED ' ) ? SOCKET_ECONNREFUSED : 111 );
339+ } elseif ($ data ['status ' ] === Server::ERROR_TTL ) {
340+ throw new RuntimeException ('SOCKS server reported TTL/timeout expired (ETIMEDOUT) ' , defined ('SOCKET_ETIMEDOUT ' ) ? SOCKET_ETIMEDOUT : 110 );
341+ } elseif ($ data ['status ' ] === Server::ERROR_COMMAND_UNSUPPORTED ) {
342+ throw new RuntimeException ('SOCKS server does not support the CONNECT command (EPROTO) ' , defined ('SOCKET_EPROTO ' ) ? SOCKET_EPROTO : 71 );
343+ } elseif ($ data ['status ' ] === Server::ERROR_ADDRESS_UNSUPPORTED ) {
344+ throw new RuntimeException ('SOCKS server does not support this address type (EPROTO) ' , defined ('SOCKET_EPROTO ' ) ? SOCKET_EPROTO : 71 );
345+ }
346+
347+ throw new RuntimeException ('SOCKS server reported an unassigned error code ' . sprintf ('0x%02X ' , $ data ['status ' ]) . ' (ECONNREFUSED) ' , defined ('SOCKET_ECONNREFUSED ' ) ? SOCKET_ECONNREFUSED : 111 );
328348 }
329349 if ($ data ['type ' ] === 0x01 ) {
330350 // IPv4 address => skip IP and port
0 commit comments