Bug 1117984: added proxy connection state enum. r=bwc

This commit is contained in:
Nils Ohlmeier [:drno] 2016-01-20 15:55:35 -08:00
parent 83599149da
commit 366f4f1c7d
3 changed files with 38 additions and 12 deletions

View File

@ -65,7 +65,7 @@ static void nr_ice_socket_readable_cb(NR_SOCKET s, int how, void *cb_arg)
NR_ASYNC_WAIT(s,how,nr_ice_socket_readable_cb,cb_arg);
if(r=nr_socket_recvfrom(sock->sock,buf,sizeof(buf),&len_s,0,&addr)){
if (r != R_WOULDBLOCK && (sock->type == NR_ICE_SOCKET_TYPE_STREAM_TURN)) {
if (r != R_WOULDBLOCK && (sock->type != NR_ICE_SOCKET_TYPE_DGRAM)) {
/* Report this error upward. Bug 946423 */
r_log(LOG_ICE,LOG_ERR,"ICE(%s): Error %d on reliable socket. Abandoning.",sock->ctx->label, r);
NR_ASYNC_CANCEL(s, NR_ASYNC_WAIT_READ);

View File

@ -47,13 +47,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
#define END_HEADERS CRLF CRLF
typedef enum {
PROXY_TUNNEL_NONE=0,
PROXY_TUNNEL_REQUESTED,
PROXY_TUNNEL_CONNECTED,
PROXY_TUNNEL_CLOSED,
PROXY_TUNNEL_FAILED
} nr_socket_proxy_tunnel_state;
typedef struct nr_socket_proxy_tunnel_ {
nr_proxy_tunnel_config *config;
nr_socket *inner;
nr_transport_addr remote_addr;
int connect_requested;
int connect_answered;
int connect_failed;
nr_socket_proxy_tunnel_state state;
char buffer[MAX_HTTP_CONNECT_BUFFER_SIZE];
size_t buffered_bytes;
void *resolver_handle;
@ -143,7 +149,7 @@ static int send_http_connect(nr_socket_proxy_tunnel *sock)
ABORT(R_IO_ERROR);
}
sock->connect_requested = 1;
sock->state = PROXY_TUNNEL_REQUESTED;
_status = 0;
abort:
@ -173,6 +179,9 @@ static int parse_http_response(char *begin, char *end, unsigned int *status)
// len should *never* be greater than nr_socket_proxy_tunnel::buffered_bytes.
// Which in turn should never be greater nr_socket_proxy_tunnel::buffer size.
assert(len <= MAX_HTTP_CONNECT_BUFFER_SIZE);
if (len > MAX_HTTP_CONNECT_BUFFER_SIZE) {
return R_BAD_DATA;
}
memcpy(response, begin, len);
response[len] = '\0';
@ -249,6 +258,10 @@ static int nr_socket_proxy_tunnel_resolved_cb(void *obj, nr_transport_addr *prox
else {
r_log(LOG_GENERIC,LOG_WARNING,"Failed to resolve proxy %s",
sock->config->proxy_host);
/* TODO: Mozilla bug 1241758: because of the callback the return value goes
* nowhere, so we can't mark the candidate as failed, so everything depends
* on the overall timeouts in this case. */
sock->state = PROXY_TUNNEL_FAILED;
ABORT(R_NOT_FOUND);
}
@ -336,13 +349,20 @@ int nr_socket_proxy_tunnel_write(void *obj, const void *msg, size_t len,
r_log(LOG_GENERIC,LOG_DEBUG,"nr_socket_proxy_tunnel_write");
if (!sock->connect_requested) {
if (sock->state >= PROXY_TUNNEL_CLOSED) {
return R_FAILED;
}
if (sock->state == PROXY_TUNNEL_NONE) {
if ((r=send_http_connect(sock))) {
ABORT(r);
}
}
/* TODO (bug 1117984): we cannot assume it's safe to write until we receive a response. */
if (sock->state != PROXY_TUNNEL_CONNECTED) {
return R_WOULDBLOCK;
}
if ((r=nr_socket_write(sock->inner, msg, len, written, 0))) {
ABORT(r);
}
@ -366,11 +386,11 @@ int nr_socket_proxy_tunnel_read(void *obj, void * restrict buf, size_t maxlen,
*len = 0;
if (sock->connect_failed) {
if (sock->state >= PROXY_TUNNEL_CLOSED) {
return R_FAILED;
}
if (sock->connect_answered) {
if (sock->state == PROXY_TUNNEL_CONNECTED) {
return nr_socket_read(sock->inner, buf, maxlen, len, 0);
}
@ -391,8 +411,6 @@ int nr_socket_proxy_tunnel_read(void *obj, void * restrict buf, size_t maxlen,
sock->buffered_bytes += bytes_read;
if (http_term = find_http_terminator(sock->buffer, sock->buffered_bytes)) {
sock->connect_answered = 1;
if ((r = parse_http_response(sock->buffer, http_term, &http_status))) {
ABORT(r);
}
@ -404,6 +422,8 @@ int nr_socket_proxy_tunnel_read(void *obj, void * restrict buf, size_t maxlen,
ABORT(R_FAILED);
}
sock->state = PROXY_TUNNEL_CONNECTED;
ptr = http_term + strlen(END_HEADERS);
pending = sock->buffered_bytes - (ptr - sock->buffer);
@ -420,7 +440,7 @@ int nr_socket_proxy_tunnel_read(void *obj, void * restrict buf, size_t maxlen,
_status=0;
abort:
if (_status && _status != R_WOULDBLOCK) {
sock->connect_failed = 1;
sock->state = PROXY_TUNNEL_FAILED;
}
return(_status);
}
@ -436,6 +456,8 @@ int nr_socket_proxy_tunnel_close(void *obj)
sock->resolver_handle = 0;
}
sock->state = PROXY_TUNNEL_CLOSED;
return nr_socket_close(sock->inner);
}

View File

@ -524,6 +524,10 @@ static void nr_socket_buffered_stun_writable_cb(NR_SOCKET s, int how, void *arg)
int r,_status;
nr_p_buf *n1, *n2;
if (sock->read_state == NR_ICE_SOCKET_READ_FAILED) {
ABORT(R_FAILED);
}
/* Try to flush */
STAILQ_FOREACH_SAFE(n1, &sock->pending_writes, entry, n2) {
size_t written = 0;