Commit 472692f7 authored by deuce's avatar deuce
Browse files

Fix up js_recv_socket() some more... add explicit MSG_WAITALL support for

TLS, use MSG_WAITALL for reading integers, add a time() based timeout,
return as soon as any bytes are read (including zero), and generally
behave more closely to how recv() itself behaves.
parent ed409b11
...@@ -155,39 +155,56 @@ static ptrdiff_t js_socket_recv(js_socket_private_t *p, void *buf, size_t len, i ...@@ -155,39 +155,56 @@ static ptrdiff_t js_socket_recv(js_socket_private_t *p, void *buf, size_t len, i
fd_set socket_set; fd_set socket_set;
struct timeval tv = {0, 0}; struct timeval tv = {0, 0};
char *estr; char *estr;
time_t now = time(NULL);
int status;
if (len == 0) if (len == 0)
return total; return total;
if(p->session==-1) { if (p->session != -1) {
FD_ZERO(&socket_set); if (do_cryptAttribute(p->session, CRYPT_OPTION_NET_READTIMEOUT, p->nonblocking?0:timeout) != CRYPT_OK)
FD_SET(p->sock,&socket_set); return -1;
tv.tv_sec = timeout;
if(select(p->sock+1,&socket_set,NULL,NULL,&tv)==1)
return(recv(p->sock, buf, len, flags)); /* Blocked here, indefinitely, in MSP-UDP service */
return 0;
} }
if (do_cryptAttribute(p->session, CRYPT_OPTION_NET_READTIMEOUT, p->nonblocking?0:timeout) != CRYPT_OK)
return -1;
do { do {
if((ret=cryptPopData(p->session, buf, len, &copied))==CRYPT_OK) { if(p->session==-1) {
if(p->nonblocking) FD_ZERO(&socket_set);
return copied; FD_SET(p->sock,&socket_set);
total += copied; tv.tv_sec = timeout;
if(total>=(ptrdiff_t)len) if(select(p->sock+1,&socket_set,NULL,NULL,&tv)==1)
return total; ret = recv(p->sock, buf, len, flags);
len-=copied; return 0;
buf=((uint8_t *)buf) + copied;
} }
else { else {
if (ret != CRYPT_ERROR_COMPLETE) status = cryptPopData(p->session, buf, len, &copied);
GCES(ret, p, estr, "popping data"); if(cryptStatusOK(status))
ret = copied;
else {
ret = -1;
if (status == CRYPT_ERROR_TIMEOUT)
ret = 0;
else if (status != CRYPT_ERROR_COMPLETE)
GCES(ret, p, estr, "popping data");
}
}
if (ret == -1) {
if (total > 0)
return total;
return ret;
}
if (!(flags & MSG_WAITALL) || p->nonblocking)
return ret;
total += copied;
if(total>=(ptrdiff_t)len)
return total;
len-=copied;
buf=((uint8_t *)buf) + copied;
if(!socket_check(p->sock,NULL,NULL,0)) {
if (total > 0) if (total > 0)
return total; return total;
do_js_close(p);
return -1; return -1;
} }
if(!socket_check(p->sock,NULL,NULL,0)) if (now + timeout > time(NULL))
break; return total;
} while(len); } while(len);
return total; return total;
} }
...@@ -1405,18 +1422,18 @@ js_recvbin(JSContext *cx, uintN argc, jsval *arglist) ...@@ -1405,18 +1422,18 @@ js_recvbin(JSContext *cx, uintN argc, jsval *arglist)
rc=JS_SUSPENDREQUEST(cx); rc=JS_SUSPENDREQUEST(cx);
switch(size) { switch(size) {
case sizeof(BYTE): case sizeof(BYTE):
if((rd=js_socket_recv(p,&b,size,0,120))==size) if((rd=js_socket_recv(p,&b,size,MSG_WAITALL,120))==size)
JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(b)); JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(b));
break; break;
case sizeof(WORD): case sizeof(WORD):
if((rd=js_socket_recv(p,(BYTE*)&w,size,0,120))==size) { if((rd=js_socket_recv(p,(BYTE*)&w,size,MSG_WAITALL,120))==size) {
if(p->network_byte_order) if(p->network_byte_order)
w=ntohs(w); w=ntohs(w);
JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(w)); JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(w));
} }
break; break;
case sizeof(DWORD): case sizeof(DWORD):
if((rd=js_socket_recv(p,(BYTE*)&l,size,0,120))==size) { if((rd=js_socket_recv(p,(BYTE*)&l,size,MSG_WAITALL,120))==size) {
if(p->network_byte_order) if(p->network_byte_order)
l=ntohl(l); l=ntohl(l);
JS_SET_RVAL(cx, arglist, UINT_TO_JSVAL(l)); JS_SET_RVAL(cx, arglist, UINT_TO_JSVAL(l));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment