Set proper timeouts for SSLSocket
If no timeout was specified in fsockopen, we passed in 0.0, which was then used as the actual timeout, meaning that while the socket opened, it almost always failed to open in ssl mode due to timeout, and then read garbage data from the socket. We also failed to pass in the specified timeout for non-ssl sockets, but there we did use the default timeout rather than 0.0. I've changed that to use the passed in timeout instead.
Esse commit está contido em:
@@ -53,15 +53,20 @@ Socket::Socket()
|
||||
}
|
||||
|
||||
Socket::Socket(int sockfd, int type, const char *address /* = NULL */,
|
||||
int port /* = 0 */)
|
||||
int port /* = 0 */, double timeout /* = 0 */)
|
||||
: File(true), m_port(port), m_type(type), m_error(0), m_eof(false),
|
||||
m_timeout(0), m_timedOut(false), m_bytesSent(0) {
|
||||
if (address) m_address = address;
|
||||
m_fd = sockfd;
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = RuntimeOption::SocketDefaultTimeout;
|
||||
tv.tv_usec = 0;
|
||||
if (timeout <= 0) {
|
||||
tv.tv_sec = RuntimeOption::SocketDefaultTimeout;
|
||||
tv.tv_usec = 0;
|
||||
} else {
|
||||
tv.tv_sec = (int)timeout;
|
||||
tv.tv_usec = (timeout - tv.tv_sec) * 1e6;
|
||||
}
|
||||
setsockopt(m_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
|
||||
s_socket_data->m_lastErrno = errno;
|
||||
setsockopt(m_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
|
||||
|
||||
@@ -38,7 +38,8 @@ public:
|
||||
// we need to support pfsockopen() that can make a socket persistent.
|
||||
|
||||
Socket();
|
||||
Socket(int sockfd, int type, const char *address = nullptr, int port = 0);
|
||||
Socket(int sockfd, int type, const char *address = nullptr, int port = 0,
|
||||
double timeout = 0);
|
||||
virtual ~Socket();
|
||||
|
||||
static StaticString s_class_name;
|
||||
|
||||
@@ -281,7 +281,8 @@ static int php_read(Socket *sock, void *buf, int maxlen, int flags) {
|
||||
}
|
||||
|
||||
static bool create_new_socket(const char *&name, int port, Variant &errnum,
|
||||
Variant &errstr, Object &ret, Socket *&sock) {
|
||||
Variant &errstr, Object &ret, Socket *&sock,
|
||||
double timeout) {
|
||||
int domain = AF_INET;
|
||||
int type = SOCK_STREAM;
|
||||
if (strncmp(name, "udp://", 6) == 0 || strncmp(name, "udg://", 6) == 0) {
|
||||
@@ -294,7 +295,7 @@ static bool create_new_socket(const char *&name, int port, Variant &errnum,
|
||||
name += 7;
|
||||
}
|
||||
|
||||
sock = new Socket(socket(domain, type, 0), domain, name, port);
|
||||
sock = new Socket(socket(domain, type, 0), domain, name, port, timeout);
|
||||
ret = Object(sock);
|
||||
if (!sock->valid()) {
|
||||
SOCKET_ERROR(sock, "unable to create socket", errno);
|
||||
@@ -664,7 +665,7 @@ Variant f_socket_server(CStrRef hostname, int port /* = -1 */,
|
||||
Object ret;
|
||||
Socket *sock = NULL;
|
||||
const char *name = hostname.data();
|
||||
if (!create_new_socket(name, port, errnum, errstr, ret, sock)) {
|
||||
if (!create_new_socket(name, port, errnum, errstr, ret, sock, 0.0)) {
|
||||
return false;
|
||||
}
|
||||
assert(ret.get() && sock);
|
||||
@@ -1000,12 +1001,14 @@ static Variant sockopen_impl(CStrRef hostname, int port, Variant &errnum,
|
||||
const char *name = hostname.data();
|
||||
Socket *sock = NULL;
|
||||
|
||||
if (timeout <= 0) timeout = RuntimeOption::SocketDefaultTimeout;
|
||||
// test if protocol is SSL
|
||||
SSLSocket *sslsock = SSLSocket::Create(name, port, timeout);
|
||||
if (sslsock) {
|
||||
sock = sslsock;
|
||||
ret = sock;
|
||||
} else if (!create_new_socket(name, port, errnum, errstr, ret, sock)) {
|
||||
} else if (!create_new_socket(name, port, errnum, errstr,
|
||||
ret, sock, timeout)) {
|
||||
return false;
|
||||
}
|
||||
assert(ret.get() && sock);
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário