static void on_read_proxy_line(h2o_socket_t *sock, int status) { struct st_h2o_accept_data_t *data = sock->data; if (status != 0) { free_accept_data(data); h2o_socket_close(sock); return; } struct sockaddr_storage addr; socklen_t addrlen; ssize_t r = parse_proxy_line(sock->input->bytes, sock->input->size, (void *)&addr, &addrlen); switch (r) { case -1: /* error, just pass the input to the next handler */ break; case -2: /* incomplete */ return; default: h2o_buffer_consume(&sock->input, r); if (addrlen != 0) h2o_socket_setpeername(sock, (void *)&addr, addrlen); break; } if (data->ctx->ssl_ctx != NULL) { h2o_socket_ssl_server_handshake(sock, data->ctx->ssl_ctx, on_ssl_handshake_complete); } else { h2o_accept_ctx_t *ctx = free_accept_data(data); sock->data = NULL; h2o_http1_accept(ctx, sock); } }
socklen_t h2o_socket_getpeername(h2o_socket_t *sock, struct sockaddr *sa) { /* return cached, if exists */ if (sock->_peername != NULL) { memcpy(sa, &sock->_peername->addr, sock->_peername->len); return sock->_peername->len; } /* call, copy to cache, and return */ socklen_t len = get_peername_uncached(sock, sa); h2o_socket_setpeername(sock, sa, len); return len; }