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:
mwilliams
2013-07-05 09:37:24 -07:00
commit de Sara Golemon
commit 0b0741103e
3 arquivos alterados com 17 adições e 8 exclusões
+8 -3
Ver Arquivo
@@ -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));
+2 -1
Ver Arquivo
@@ -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;
+7 -4
Ver Arquivo
@@ -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);