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.
|
# binding responses.
|
||||||
#
|
#
|
||||||
response-origin-only-with-rfc5780
|
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, /* log_binding */
|
||||||
0, /* no_stun_backward_compatibility */
|
0, /* no_stun_backward_compatibility */
|
||||||
0 /* response_origin_only_with_rfc5780 */
|
0, /* response_origin_only_with_rfc5780 */
|
||||||
|
0 /* respond_http_unsupported */
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////// OpenSSL Init //////////////////////
|
//////////////// OpenSSL Init //////////////////////
|
||||||
@ -1271,6 +1272,10 @@ static char Usage[] =
|
|||||||
" in binding response (use only the XOR-MAPPED-ADDRESS).\n"
|
" in binding response (use only the XOR-MAPPED-ADDRESS).\n"
|
||||||
" --response-origin-only-with-rfc5780 Only send RESPONSE-ORIGIN attribute in binding response if "
|
" --response-origin-only-with-rfc5780 Only send RESPONSE-ORIGIN attribute in binding response if "
|
||||||
"RFC5780 is enabled.\n"
|
"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"
|
" --version Print version (and exit).\n"
|
||||||
" -h Help\n"
|
" -h Help\n"
|
||||||
"\n";
|
"\n";
|
||||||
@ -1426,6 +1431,7 @@ enum EXTRA_OPTS {
|
|||||||
NO_RFC5780,
|
NO_RFC5780,
|
||||||
NO_STUN_BACKWARD_COMPATIBILITY_OPT,
|
NO_STUN_BACKWARD_COMPATIBILITY_OPT,
|
||||||
RESPONSE_ORIGIN_ONLY_WITH_RFC5780_OPT,
|
RESPONSE_ORIGIN_ONLY_WITH_RFC5780_OPT,
|
||||||
|
RESPOND_HTTP_UNSUPPORTED_OPT,
|
||||||
VERSION_OPT
|
VERSION_OPT
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1568,6 +1574,7 @@ static const struct myoption long_options[] = {
|
|||||||
{"no-rfc5780", optional_argument, NULL, NO_RFC5780},
|
{"no-rfc5780", optional_argument, NULL, NO_RFC5780},
|
||||||
{"no-stun-backward-compatibility", optional_argument, NULL, NO_STUN_BACKWARD_COMPATIBILITY_OPT},
|
{"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},
|
{"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},
|
{"version", optional_argument, NULL, VERSION_OPT},
|
||||||
{"syslog-facility", required_argument, NULL, SYSLOG_FACILITY_OPT},
|
{"syslog-facility", required_argument, NULL, SYSLOG_FACILITY_OPT},
|
||||||
{NULL, no_argument, NULL, 0}};
|
{NULL, no_argument, NULL, 0}};
|
||||||
@ -2263,6 +2270,9 @@ static void set_option(int c, char *value) {
|
|||||||
case RESPONSE_ORIGIN_ONLY_WITH_RFC5780_OPT:
|
case RESPONSE_ORIGIN_ONLY_WITH_RFC5780_OPT:
|
||||||
turn_params.response_origin_only_with_rfc5780 = get_bool_value(value);
|
turn_params.response_origin_only_with_rfc5780 = get_bool_value(value);
|
||||||
break;
|
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: */
|
/* these options have been already taken care of before: */
|
||||||
case 'l':
|
case 'l':
|
||||||
|
|||||||
@ -330,6 +330,7 @@ typedef struct _turn_params_ {
|
|||||||
vint log_binding;
|
vint log_binding;
|
||||||
vint no_stun_backward_compatibility;
|
vint no_stun_backward_compatibility;
|
||||||
vint response_origin_only_with_rfc5780;
|
vint response_origin_only_with_rfc5780;
|
||||||
|
vint respond_http_unsupported;
|
||||||
} turn_params_t;
|
} turn_params_t;
|
||||||
|
|
||||||
extern turn_params_t turn_params;
|
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_setcb(rs->auth_in_buf, relay_receive_auth_message, NULL, NULL, rs);
|
||||||
bufferevent_enable(rs->auth_in_buf, EV_READ);
|
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(
|
||||||
DONT_FRAGMENT_SUPPORTED, start_user_check, check_new_allocation_quota, release_allocation_quota,
|
&(rs->server), rs->id, turn_params.verbose, rs->ioa_eng, turn_params.ct, 0, turn_params.fingerprint,
|
||||||
turn_params.external_ip, &turn_params.check_origin, &turn_params.no_tcp_relay,
|
DONT_FRAGMENT_SUPPORTED, start_user_check, check_new_allocation_quota, release_allocation_quota,
|
||||||
&turn_params.no_udp_relay, &turn_params.stale_nonce, &turn_params.max_allocate_lifetime,
|
turn_params.external_ip, &turn_params.check_origin, &turn_params.no_tcp_relay, &turn_params.no_udp_relay,
|
||||||
&turn_params.channel_lifetime, &turn_params.permission_lifetime, &turn_params.stun_only,
|
&turn_params.stale_nonce, &turn_params.max_allocate_lifetime, &turn_params.channel_lifetime,
|
||||||
&turn_params.no_stun, &turn_params.no_software_attribute, &turn_params.web_admin_listen_on_workers,
|
&turn_params.permission_lifetime, &turn_params.stun_only, &turn_params.no_stun,
|
||||||
&turn_params.alternate_servers_list, &turn_params.tls_alternate_servers_list,
|
&turn_params.no_software_attribute, &turn_params.web_admin_listen_on_workers, &turn_params.alternate_servers_list,
|
||||||
&turn_params.aux_servers_list, turn_params.udp_self_balance, &turn_params.no_multicast_peers,
|
&turn_params.tls_alternate_servers_list, &turn_params.aux_servers_list, turn_params.udp_self_balance,
|
||||||
&turn_params.allow_loopback_peers, &turn_params.ip_whitelist, &turn_params.ip_blacklist,
|
&turn_params.no_multicast_peers, &turn_params.allow_loopback_peers, &turn_params.ip_whitelist,
|
||||||
send_socket_to_relay, &turn_params.secure_stun, &turn_params.mobility, turn_params.server_relay,
|
&turn_params.ip_blacklist, send_socket_to_relay, &turn_params.secure_stun, &turn_params.mobility,
|
||||||
send_turn_session_info, send_https_socket, allocate_bps, turn_params.oauth,
|
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.oauth_server_name, turn_params.acme_redirect, turn_params.allocation_default_address_family,
|
||||||
turn_params.allocation_default_address_family, &turn_params.log_binding,
|
&turn_params.log_binding, &turn_params.no_stun_backward_compatibility,
|
||||||
&turn_params.no_stun_backward_compatibility, &turn_params.response_origin_only_with_rfc5780);
|
&turn_params.response_origin_only_with_rfc5780, &turn_params.respond_http_unsupported);
|
||||||
|
|
||||||
if (to_set_rfc5780) {
|
if (to_set_rfc5780) {
|
||||||
set_rfc5780(&(rs->server), get_alt_addr, send_message_from_listener_to_client);
|
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_stream_socket(st)) {
|
||||||
if (is_http((char *)ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh))) {
|
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),
|
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,
|
ioa_network_buffer_get_size(in_buffer->nbh), server->acme_redirect,
|
||||||
ss->client_socket) == 0)) {
|
ss->client_socket) == 0)) {
|
||||||
@ -4505,7 +4506,6 @@ static int read_client_connection(turn_turnserver *server, ts_ur_super_session *
|
|||||||
return 0;
|
return 0;
|
||||||
} else if (*server->web_admin_listen_on_workers) {
|
} else if (*server->web_admin_listen_on_workers) {
|
||||||
if (st == TLS_SOCKET) {
|
if (st == TLS_SOCKET) {
|
||||||
proto = "HTTPS";
|
|
||||||
set_ioa_socket_app_type(ss->client_socket, HTTPS_CLIENT_SOCKET);
|
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,
|
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),
|
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);
|
handle_http_echo(ss->client_socket);
|
||||||
}
|
}
|
||||||
return 0;
|
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 {
|
} else {
|
||||||
ss->to_be_closed = 1;
|
ss->to_be_closed = 1;
|
||||||
return 0;
|
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,
|
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,
|
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,
|
const char *acme_redirect, ALLOCATION_DEFAULT_ADDRESS_FAMILY allocation_default_address_family,
|
||||||
vintp log_binding, vintp no_stun_backward_compatibility,
|
vintp log_binding, vintp no_stun_backward_compatibility, vintp response_origin_only_with_rfc5780,
|
||||||
vintp response_origin_only_with_rfc5780) {
|
vintp respond_http_unsupported) {
|
||||||
|
|
||||||
if (!server)
|
if (!server)
|
||||||
return;
|
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->no_stun_backward_compatibility = no_stun_backward_compatibility;
|
||||||
|
|
||||||
server->response_origin_only_with_rfc5780 = response_origin_only_with_rfc5780;
|
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) {
|
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 */
|
/* Only send RESPONSE-ORIGIN attribute in response if RFC5780 is enabled */
|
||||||
vintp response_origin_only_with_rfc5780;
|
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);
|
const char *get_version(turn_turnserver *server);
|
||||||
|
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
|
|
||||||
void init_turn_server(turn_turnserver *server, turnserver_id id, int verbose, ioa_engine_handle e,
|
void init_turn_server(
|
||||||
turn_credential_type ct, int stun_port, int fingerprint, dont_fragment_option_t dont_fragment,
|
turn_turnserver *server, turnserver_id id, int verbose, ioa_engine_handle e, turn_credential_type ct, int stun_port,
|
||||||
get_user_key_cb userkeycb, check_new_allocation_quota_cb chquotacb,
|
int fingerprint, dont_fragment_option_t dont_fragment, get_user_key_cb userkeycb,
|
||||||
release_allocation_quota_cb raqcb, ioa_addr *external_addr, vintp check_origin,
|
check_new_allocation_quota_cb chquotacb, release_allocation_quota_cb raqcb, ioa_addr *external_addr,
|
||||||
vintp no_tcp_relay, vintp no_udp_relay, vintp stale_nonce, vintp max_allocate_lifetime,
|
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 channel_lifetime, vintp permission_lifetime, vintp stun_only, vintp no_stun, vintp no_software_attribute,
|
||||||
vintp no_software_attribute, vintp web_admin_listen_on_workers,
|
vintp web_admin_listen_on_workers, turn_server_addrs_list_t *alternate_servers_list,
|
||||||
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,
|
||||||
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,
|
||||||
int self_udp_balance, vintp no_multicast_peers, vintp allow_loopback_peers,
|
ip_range_list_t *ip_blacklist, send_socket_to_relay_cb send_socket_to_relay, vintp secure_stun, vintp mobility,
|
||||||
ip_range_list_t *ip_whitelist, ip_range_list_t *ip_blacklist,
|
int server_relay, send_turn_session_info_cb send_turn_session_info, send_https_socket_cb send_https_socket,
|
||||||
send_socket_to_relay_cb send_socket_to_relay, vintp secure_stun, vintp mobility, int server_relay,
|
allocate_bps_cb allocate_bps_func, int oauth, const char *oauth_server_name, const char *acme_redirect,
|
||||||
send_turn_session_info_cb send_turn_session_info, send_https_socket_cb send_https_socket,
|
ALLOCATION_DEFAULT_ADDRESS_FAMILY allocation_default_address_family, vintp log_binding,
|
||||||
allocate_bps_cb allocate_bps_func, int oauth, const char *oauth_server_name,
|
vintp no_stun_backward_compatibility, vintp response_origin_only_with_rfc5780, vintp respond_http_unsupported);
|
||||||
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);
|
|
||||||
|
|
||||||
ioa_engine_handle turn_server_get_engine(turn_turnserver *s);
|
ioa_engine_handle turn_server_get_engine(turn_turnserver *s);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user