mirror of
https://github.com/coturn/coturn.git
synced 2025-10-26 20:41:07 +01:00
Return a 400 response to HTTP requests (#1231)
For our deployment, it is useful if coturn returns a valid HTTP response to an HTTP request. To do this on the same port as STUN/TURN and without enabling the admin site, I have extended `read_client_connection()` to return a canned HTTP response, in response to an HTTP request, rather than immediately closing the connection.
This commit is contained in:
parent
0fb6addecb
commit
20c8d86a34
@ -797,3 +797,9 @@ no-stun-backward-compatibility
|
||||
# binding responses.
|
||||
#
|
||||
response-origin-only-with-rfc5780
|
||||
|
||||
# Return an HTTP/S response when an HTTP/S connection is made to a TCP port
|
||||
# otherwise only supporting STUN/TURN. This may be useful for debugging and
|
||||
# diagnosing connection problems. A "400 Not supported" response is currently
|
||||
# returned.
|
||||
#respond-http-unsupported
|
||||
|
||||
@ -231,7 +231,8 @@ turn_params_t turn_params = {
|
||||
|
||||
0, /* log_binding */
|
||||
0, /* no_stun_backward_compatibility */
|
||||
0 /* response_origin_only_with_rfc5780 */
|
||||
0, /* response_origin_only_with_rfc5780 */
|
||||
0 /* respond_http_unsupported */
|
||||
};
|
||||
|
||||
//////////////// OpenSSL Init //////////////////////
|
||||
@ -1271,6 +1272,10 @@ static char Usage[] =
|
||||
" in binding response (use only the XOR-MAPPED-ADDRESS).\n"
|
||||
" --response-origin-only-with-rfc5780 Only send RESPONSE-ORIGIN attribute in binding response if "
|
||||
"RFC5780 is enabled.\n"
|
||||
" --respond-http-unsupported Return an HTTP reponse with a 400 status code to HTTP "
|
||||
"connections made to ports not\n"
|
||||
" supporting HTTP. The default behaviour is to immediately "
|
||||
"close the connection.\n"
|
||||
" --version Print version (and exit).\n"
|
||||
" -h Help\n"
|
||||
"\n";
|
||||
@ -1426,6 +1431,7 @@ enum EXTRA_OPTS {
|
||||
NO_RFC5780,
|
||||
NO_STUN_BACKWARD_COMPATIBILITY_OPT,
|
||||
RESPONSE_ORIGIN_ONLY_WITH_RFC5780_OPT,
|
||||
RESPOND_HTTP_UNSUPPORTED_OPT,
|
||||
VERSION_OPT
|
||||
};
|
||||
|
||||
@ -1568,6 +1574,7 @@ static const struct myoption long_options[] = {
|
||||
{"no-rfc5780", optional_argument, NULL, NO_RFC5780},
|
||||
{"no-stun-backward-compatibility", optional_argument, NULL, NO_STUN_BACKWARD_COMPATIBILITY_OPT},
|
||||
{"response-origin-only-with-rfc5780", optional_argument, NULL, RESPONSE_ORIGIN_ONLY_WITH_RFC5780_OPT},
|
||||
{"respond-http-unsupported", optional_argument, NULL, RESPOND_HTTP_UNSUPPORTED_OPT},
|
||||
{"version", optional_argument, NULL, VERSION_OPT},
|
||||
{"syslog-facility", required_argument, NULL, SYSLOG_FACILITY_OPT},
|
||||
{NULL, no_argument, NULL, 0}};
|
||||
@ -2263,6 +2270,9 @@ static void set_option(int c, char *value) {
|
||||
case RESPONSE_ORIGIN_ONLY_WITH_RFC5780_OPT:
|
||||
turn_params.response_origin_only_with_rfc5780 = get_bool_value(value);
|
||||
break;
|
||||
case RESPOND_HTTP_UNSUPPORTED_OPT:
|
||||
turn_params.respond_http_unsupported = get_bool_value(value);
|
||||
break;
|
||||
|
||||
/* these options have been already taken care of before: */
|
||||
case 'l':
|
||||
|
||||
@ -330,6 +330,7 @@ typedef struct _turn_params_ {
|
||||
vint log_binding;
|
||||
vint no_stun_backward_compatibility;
|
||||
vint response_origin_only_with_rfc5780;
|
||||
vint respond_http_unsupported;
|
||||
} turn_params_t;
|
||||
|
||||
extern turn_params_t turn_params;
|
||||
|
||||
@ -1621,20 +1621,20 @@ static void setup_relay_server(struct relay_server *rs, ioa_engine_handle e, int
|
||||
bufferevent_setcb(rs->auth_in_buf, relay_receive_auth_message, NULL, NULL, rs);
|
||||
bufferevent_enable(rs->auth_in_buf, EV_READ);
|
||||
|
||||
init_turn_server(&(rs->server), rs->id, turn_params.verbose, rs->ioa_eng, turn_params.ct, 0, turn_params.fingerprint,
|
||||
init_turn_server(
|
||||
&(rs->server), rs->id, turn_params.verbose, rs->ioa_eng, turn_params.ct, 0, turn_params.fingerprint,
|
||||
DONT_FRAGMENT_SUPPORTED, start_user_check, check_new_allocation_quota, release_allocation_quota,
|
||||
turn_params.external_ip, &turn_params.check_origin, &turn_params.no_tcp_relay,
|
||||
&turn_params.no_udp_relay, &turn_params.stale_nonce, &turn_params.max_allocate_lifetime,
|
||||
&turn_params.channel_lifetime, &turn_params.permission_lifetime, &turn_params.stun_only,
|
||||
&turn_params.no_stun, &turn_params.no_software_attribute, &turn_params.web_admin_listen_on_workers,
|
||||
&turn_params.alternate_servers_list, &turn_params.tls_alternate_servers_list,
|
||||
&turn_params.aux_servers_list, turn_params.udp_self_balance, &turn_params.no_multicast_peers,
|
||||
&turn_params.allow_loopback_peers, &turn_params.ip_whitelist, &turn_params.ip_blacklist,
|
||||
send_socket_to_relay, &turn_params.secure_stun, &turn_params.mobility, turn_params.server_relay,
|
||||
send_turn_session_info, send_https_socket, allocate_bps, turn_params.oauth,
|
||||
turn_params.oauth_server_name, turn_params.acme_redirect,
|
||||
turn_params.allocation_default_address_family, &turn_params.log_binding,
|
||||
&turn_params.no_stun_backward_compatibility, &turn_params.response_origin_only_with_rfc5780);
|
||||
turn_params.external_ip, &turn_params.check_origin, &turn_params.no_tcp_relay, &turn_params.no_udp_relay,
|
||||
&turn_params.stale_nonce, &turn_params.max_allocate_lifetime, &turn_params.channel_lifetime,
|
||||
&turn_params.permission_lifetime, &turn_params.stun_only, &turn_params.no_stun,
|
||||
&turn_params.no_software_attribute, &turn_params.web_admin_listen_on_workers, &turn_params.alternate_servers_list,
|
||||
&turn_params.tls_alternate_servers_list, &turn_params.aux_servers_list, turn_params.udp_self_balance,
|
||||
&turn_params.no_multicast_peers, &turn_params.allow_loopback_peers, &turn_params.ip_whitelist,
|
||||
&turn_params.ip_blacklist, send_socket_to_relay, &turn_params.secure_stun, &turn_params.mobility,
|
||||
turn_params.server_relay, send_turn_session_info, send_https_socket, allocate_bps, turn_params.oauth,
|
||||
turn_params.oauth_server_name, turn_params.acme_redirect, turn_params.allocation_default_address_family,
|
||||
&turn_params.log_binding, &turn_params.no_stun_backward_compatibility,
|
||||
&turn_params.response_origin_only_with_rfc5780, &turn_params.respond_http_unsupported);
|
||||
|
||||
if (to_set_rfc5780) {
|
||||
set_rfc5780(&(rs->server), get_alt_addr, send_message_from_listener_to_client);
|
||||
|
||||
@ -4497,7 +4497,8 @@ static int read_client_connection(turn_turnserver *server, ts_ur_super_session *
|
||||
if (is_stream_socket(st)) {
|
||||
if (is_http((char *)ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh))) {
|
||||
|
||||
const char *proto = "HTTP";
|
||||
const char *proto = st == TLS_SOCKET ? "HTTPS" : "HTTP";
|
||||
|
||||
if ((st == TCP_SOCKET) && (try_acme_redirect((char *)ioa_network_buffer_data(in_buffer->nbh),
|
||||
ioa_network_buffer_get_size(in_buffer->nbh), server->acme_redirect,
|
||||
ss->client_socket) == 0)) {
|
||||
@ -4505,7 +4506,6 @@ static int read_client_connection(turn_turnserver *server, ts_ur_super_session *
|
||||
return 0;
|
||||
} else if (*server->web_admin_listen_on_workers) {
|
||||
if (st == TLS_SOCKET) {
|
||||
proto = "HTTPS";
|
||||
set_ioa_socket_app_type(ss->client_socket, HTTPS_CLIENT_SOCKET);
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s (%s %s) request: %zu\n", __FUNCTION__, proto,
|
||||
get_ioa_socket_cipher(ss->client_socket), get_ioa_socket_ssl_method(ss->client_socket),
|
||||
@ -4531,6 +4531,36 @@ static int read_client_connection(turn_turnserver *server, ts_ur_super_session *
|
||||
handle_http_echo(ss->client_socket);
|
||||
}
|
||||
return 0;
|
||||
} else if (*server->respond_http_unsupported) {
|
||||
/* Our incoming connection is HTTP, but we are not serving the
|
||||
* admin site. Return a 400 response. */
|
||||
if (st == TLS_SOCKET) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s (%s %s) returning 400 response: %zu\n", __FUNCTION__, proto,
|
||||
get_ioa_socket_cipher(ss->client_socket), get_ioa_socket_ssl_method(ss->client_socket),
|
||||
ioa_network_buffer_get_size(in_buffer->nbh));
|
||||
set_ioa_socket_app_type(ss->client_socket, HTTPS_CLIENT_SOCKET);
|
||||
} else {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s returning 400 response", __FUNCTION__, proto);
|
||||
}
|
||||
|
||||
ioa_network_buffer_handle nbh_http = ioa_network_buffer_allocate(ss->client_socket->e);
|
||||
|
||||
/* HTTP content */
|
||||
char *content = "HTTP not supported.\n";
|
||||
|
||||
/* Measure length of content */
|
||||
int content_length = strlen(content);
|
||||
|
||||
/* Construct full response */
|
||||
char buffer[1024];
|
||||
snprintf(buffer, sizeof(buffer),
|
||||
"HTTP/1.1 400 %s Not supported\r\nConnection: close\r\nContent-Type: "
|
||||
"text/plain\r\nContent-Length: %d\r\n\r\n%s",
|
||||
proto, content_length, content);
|
||||
|
||||
ioa_network_buffer_set_size(nbh_http, strlen(buffer));
|
||||
memcpy(ioa_network_buffer_data(nbh_http), buffer, strlen(buffer));
|
||||
send_data_from_ioa_socket_nbh(ss->client_socket, NULL, nbh_http, TTL_IGNORE, TOS_IGNORE, NULL);
|
||||
} else {
|
||||
ss->to_be_closed = 1;
|
||||
return 0;
|
||||
@ -4774,8 +4804,8 @@ void init_turn_server(turn_turnserver *server, turnserver_id id, int verbose, io
|
||||
send_turn_session_info_cb send_turn_session_info, send_https_socket_cb send_https_socket,
|
||||
allocate_bps_cb allocate_bps_func, int oauth, const char *oauth_server_name,
|
||||
const char *acme_redirect, ALLOCATION_DEFAULT_ADDRESS_FAMILY allocation_default_address_family,
|
||||
vintp log_binding, vintp no_stun_backward_compatibility,
|
||||
vintp response_origin_only_with_rfc5780) {
|
||||
vintp log_binding, vintp no_stun_backward_compatibility, vintp response_origin_only_with_rfc5780,
|
||||
vintp respond_http_unsupported) {
|
||||
|
||||
if (!server)
|
||||
return;
|
||||
@ -4853,6 +4883,8 @@ void init_turn_server(turn_turnserver *server, turnserver_id id, int verbose, io
|
||||
server->no_stun_backward_compatibility = no_stun_backward_compatibility;
|
||||
|
||||
server->response_origin_only_with_rfc5780 = response_origin_only_with_rfc5780;
|
||||
|
||||
server->respond_http_unsupported = respond_http_unsupported;
|
||||
}
|
||||
|
||||
ioa_engine_handle turn_server_get_engine(turn_turnserver *s) {
|
||||
|
||||
@ -194,28 +194,30 @@ struct _turn_turnserver {
|
||||
|
||||
/* Only send RESPONSE-ORIGIN attribute in response if RFC5780 is enabled */
|
||||
vintp response_origin_only_with_rfc5780;
|
||||
|
||||
/* Return an HTTP 400 response to HTTP connections made to ports not
|
||||
otherwise handling HTTP. */
|
||||
vintp respond_http_unsupported;
|
||||
};
|
||||
|
||||
const char *get_version(turn_turnserver *server);
|
||||
|
||||
///////////////////////////////////////////
|
||||
|
||||
void init_turn_server(turn_turnserver *server, turnserver_id id, int verbose, ioa_engine_handle e,
|
||||
turn_credential_type ct, int stun_port, int fingerprint, dont_fragment_option_t dont_fragment,
|
||||
get_user_key_cb userkeycb, check_new_allocation_quota_cb chquotacb,
|
||||
release_allocation_quota_cb raqcb, ioa_addr *external_addr, vintp check_origin,
|
||||
vintp no_tcp_relay, vintp no_udp_relay, vintp stale_nonce, vintp max_allocate_lifetime,
|
||||
vintp channel_lifetime, vintp permission_lifetime, vintp stun_only, vintp no_stun,
|
||||
vintp no_software_attribute, vintp web_admin_listen_on_workers,
|
||||
turn_server_addrs_list_t *alternate_servers_list,
|
||||
void init_turn_server(
|
||||
turn_turnserver *server, turnserver_id id, int verbose, ioa_engine_handle e, turn_credential_type ct, int stun_port,
|
||||
int fingerprint, dont_fragment_option_t dont_fragment, get_user_key_cb userkeycb,
|
||||
check_new_allocation_quota_cb chquotacb, release_allocation_quota_cb raqcb, ioa_addr *external_addr,
|
||||
vintp check_origin, vintp no_tcp_relay, vintp no_udp_relay, vintp stale_nonce, vintp max_allocate_lifetime,
|
||||
vintp channel_lifetime, vintp permission_lifetime, vintp stun_only, vintp no_stun, vintp no_software_attribute,
|
||||
vintp web_admin_listen_on_workers, turn_server_addrs_list_t *alternate_servers_list,
|
||||
turn_server_addrs_list_t *tls_alternate_servers_list, turn_server_addrs_list_t *aux_servers_list,
|
||||
int self_udp_balance, vintp no_multicast_peers, vintp allow_loopback_peers,
|
||||
ip_range_list_t *ip_whitelist, ip_range_list_t *ip_blacklist,
|
||||
send_socket_to_relay_cb send_socket_to_relay, vintp secure_stun, vintp mobility, int server_relay,
|
||||
send_turn_session_info_cb send_turn_session_info, send_https_socket_cb send_https_socket,
|
||||
allocate_bps_cb allocate_bps_func, int oauth, const char *oauth_server_name,
|
||||
const char *acme_redirect, ALLOCATION_DEFAULT_ADDRESS_FAMILY allocation_default_address_family,
|
||||
vintp log_binding, vintp no_stun_backward_compatibility, vintp response_origin_only_with_rfc5780);
|
||||
int self_udp_balance, vintp no_multicast_peers, vintp allow_loopback_peers, ip_range_list_t *ip_whitelist,
|
||||
ip_range_list_t *ip_blacklist, send_socket_to_relay_cb send_socket_to_relay, vintp secure_stun, vintp mobility,
|
||||
int server_relay, send_turn_session_info_cb send_turn_session_info, send_https_socket_cb send_https_socket,
|
||||
allocate_bps_cb allocate_bps_func, int oauth, const char *oauth_server_name, const char *acme_redirect,
|
||||
ALLOCATION_DEFAULT_ADDRESS_FAMILY allocation_default_address_family, vintp log_binding,
|
||||
vintp no_stun_backward_compatibility, vintp response_origin_only_with_rfc5780, vintp respond_http_unsupported);
|
||||
|
||||
ioa_engine_handle turn_server_get_engine(turn_turnserver *s);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user