;tcp_keepalive_interval_time=10 ; The time in seconds between individual keepalive probes
;tcp_keepalive_probe_count=5 ; The maximum number of keepalive probes TCP should send before dropping the connection
-;===============ENDPOINT IDENTIFIER TRANSPORT EXAMPLE==========================
-;
-; When Asterisk has multiple bound IP addresses, and endpoints don't use any
-; other means of identification (e.g.: username), the transports' bind addresses
-; can be used to identify them. Can be useful in case you're connecting to the
-; same ITSP multiple times on different IPs / NICs.
-;
-;[transport-eth0]
-;type=transport
-;protocol=tcp
-;bind=192.168.1.1:5060
-;
-;[transport-eth1]
-;type=transport
-;protocol=udp
-;bind=192.168.2.1:5060
-;
-;
-;[myprovider-a]
-;type=endpoint
-;transport=transport-eth0
-;identify_by=transport
-;
-;[myprovider-b]
-;type=endpoint
-;transport=transport-eth1
-;identify_by=transport
-;
-;
-;[identify-a]
-;type=identify
-;endpoint=myprovider-a
-;match=192.168.1.1:5060 ; This is the bind address of [transport-eth0]
-;;transport=tcp ; Optionally, this is the transport protocol of [transport-eth0]
-;
-;[identify-b]
-;type=identify
-;endpoint=myprovider-b
-;match=192.168.2.1:5060 ; This is the bind address of [transport-eth1]
-;;transport=udp ; Optionally, This is the transport protocol of [transport-eth1]
-
;===============OUTBOUND REGISTRATION WITH OUTBOUND AUTHENTICATION============
;
; This is a simple registration that works with some SIP trunking providers.
; identified.
; "username": Identify by the From or To username and domain
; "auth_username": Identify by the Authorization username and realm
- ; "ip": Identify by the source (remote) IP address
+ ; "ip": Identify by the source IP address
; "header": Identify by a configured SIP header value.
; "request_uri": Identify by the configured SIP request URI.
- ; "transport": Identify by the bound (local) IP address
; In the username and auth_username cases, if an exact match
; on both username and domain/realm fails, the match is
; retried with just the username.
; (default: "no")
;endpoint_identifier_order=ip,username,anonymous
; The order by which endpoint identifiers are given priority.
- ; Currently, "ip", "header", "request_uri", "transport", "username",
- ; "auth_username" and "anonymous" are valid identifiers as registered by
- ; the res_pjsip_endpoint_identifier_* modules.
- ; Some modules like res_pjsip_endpoint_identifier_user register
+ ; Currently, "ip", "header", "username", "auth_username" and "anonymous"
+ ; are valid identifiers as registered by the res_pjsip_endpoint_identifier_*
+ ; modules. Some modules like res_pjsip_endpoint_identifier_user register
; more than one identifier. Use the CLI command "pjsip show identifiers"
; to see the identifiers currently available.
; (default: ip,username,anonymous)
;match= ; Comma separated list of IP addresses, networks, or hostnames to match
; against (default: "")
;match_header= ; SIP header with specified value to match against (default: "")
-;match_request_uri= ; SIP request URI to match against (default: "")
-;transport= ; Match ageinst the transport protocol (tcp or udp) (default: "")
;type= ; Must be of type identify (default: "")
</para></note>
</description>
</configOption>
- <configOption name="transport">
- <synopsis>Match against a transport type.</synopsis>
- <description>
- <para>When using the ip or transport identifier, this option
- can be used to match the transport type <literal>(udp or tcp)
- </literal> as well.</para>
- <para>When omitted, or left empty, which is the default, it
- won't match against the transport type.</para>
- </description>
- </configOption>
<configOption name="type">
<synopsis>Must be of type 'identify'.</synopsis>
</configOption>
AST_STRING_FIELD(match_header_name);
/*! SIP header value of the match_header string */
AST_STRING_FIELD(match_header_value);
- /*! The name of the transport type */
- AST_STRING_FIELD(transport);
);
/*! Compiled match_header regular expression when is_header_regex is non-zero */
regex_t regex_header_buf;
unsigned int is_request_uri_regex:1;
};
-/*! \brief Structure for a socket address with transport */
-struct ast_sockaddr_with_tp {
- struct ast_sockaddr addr;
- char tp[128];
-};
-
/*! \brief Destructor function for a matching object */
static void ip_identify_destroy(void *obj)
{
static int ip_identify_match_check(void *obj, void *arg, int flags)
{
struct ip_identify_match *identify = obj;
- struct ast_sockaddr_with_tp *addr_with_tp = arg;
- struct ast_sockaddr address = addr_with_tp->addr;
+ struct ast_sockaddr *addr = arg;
int sense;
- sense = ast_apply_ha(identify->matches, &address);
+ sense = ast_apply_ha(identify->matches, addr);
if (sense != AST_SENSE_ALLOW) {
- ast_debug(3, "Address %s matches identify '%s'\n",
- ast_sockaddr_stringify(&address),
- ast_sorcery_object_get_id(identify));
- if (ast_strlen_zero(identify->transport) || !strcasecmp(identify->transport, addr_with_tp->tp)) {
- ast_debug(3, "Transport %s matches identify '%s'\n",
- addr_with_tp->tp,
- ast_sorcery_object_get_id(identify));
- return CMP_MATCH;
- } else {
- ast_debug(3, "Transport %s match not matched identify '%s'\n",
- addr_with_tp->tp,
+ ast_debug(3, "Source address %s matches identify '%s'\n",
+ ast_sockaddr_stringify(addr),
ast_sorcery_object_get_id(identify));
- return 0;
- }
+ return CMP_MATCH;
} else {
- ast_debug(3, "Address %s does not match identify '%s'\n",
- ast_sockaddr_stringify(&address),
+ ast_debug(3, "Source address %s does not match identify '%s'\n",
+ ast_sockaddr_stringify(addr),
ast_sorcery_object_get_id(identify));
return 0;
}
static struct ast_sip_endpoint *ip_identify(pjsip_rx_data *rdata)
{
- struct ast_sockaddr_with_tp addr_with_tp = { { { 0, } }, };
- pj_ansi_strxcpy(addr_with_tp.tp, rdata->tp_info.transport->type_name, sizeof(addr_with_tp.tp));
-
- ast_sockaddr_parse(&addr_with_tp.addr, rdata->pkt_info.src_name, PARSE_PORT_FORBID);
- ast_sockaddr_set_port(&addr_with_tp.addr, rdata->pkt_info.src_port);
-
- return common_identify(ip_identify_match_check, &addr_with_tp);
-}
-
-static struct ast_sip_endpoint *transport_identify(pjsip_rx_data *rdata)
-{
- char buffer[PJ_INET6_ADDRSTRLEN];
- pj_status_t status;
- struct ast_sockaddr_with_tp addr_with_tp = { { { 0, } }, };
- union pj_sockaddr sock = rdata->tp_info.transport->local_addr;
-
- pj_ansi_strxcpy(addr_with_tp.tp, rdata->tp_info.transport->type_name, sizeof(addr_with_tp.tp));
-
- if (sock.addr.sa_family == PJ_AF_INET6) {
- status = pj_inet_ntop(PJ_AF_INET6, &(sock.ipv6.sin6_addr), buffer, PJ_INET6_ADDRSTRLEN);
- if (status == PJ_SUCCESS && !strcmp(buffer, "::")) {
- ast_log(LOG_WARNING, "Matching against '::' may be unpredictable.\n");
- }
- } else {
- status = pj_inet_ntop(PJ_AF_INET, &(sock.ipv4.sin_addr), buffer, PJ_INET_ADDRSTRLEN);
- if (status == PJ_SUCCESS && !strcmp(buffer, "0.0.0.0")) {
- ast_log(LOG_WARNING, "Matching against '0.0.0.0' may be unpredictable.\n");
- }
- }
+ struct ast_sockaddr addr = { { 0, } };
- if (status == PJ_SUCCESS) {
- ast_sockaddr_parse(&addr_with_tp.addr, buffer, PARSE_PORT_FORBID);
- ast_sockaddr_set_port(&addr_with_tp.addr, rdata->tp_info.transport->local_name.port);
+ ast_sockaddr_parse(&addr, rdata->pkt_info.src_name, PARSE_PORT_FORBID);
+ ast_sockaddr_set_port(&addr, rdata->pkt_info.src_port);
- return common_identify(ip_identify_match_check, &addr_with_tp);
- } else {
- return NULL;
- }
+ return common_identify(ip_identify_match_check, &addr);
}
static struct ast_sip_endpoint_identifier ip_identifier = {
.identify_endpoint = ip_identify,
};
-static struct ast_sip_endpoint_identifier transport_identifier = {
- .identify_endpoint = transport_identify,
-};
-
static struct ast_sip_endpoint *header_identify(pjsip_rx_data *rdata)
{
return common_identify(header_identify_match_check, rdata);
return -1;
}
- if (!ast_strlen_zero(identify->transport)) {
- if (ast_string_field_set(identify, transport, identify->transport)) {
- return -1;
- }
- }
-
if (!ast_strlen_zero(identify->match_header)) {
char *c_header;
char *c_value;
addr, ast_sockaddr_cidr_bits(&match->netmask));
}
- if (!ast_strlen_zero(ident->transport)) {
- ast_str_append(&context->output_buffer, 0, "%*s: %s\n",
- indent,
- "Transport",
- ident->transport);
- }
-
if (!ast_strlen_zero(ident->match_header)) {
ast_str_append(&context->output_buffer, 0, "%*s: %s\n",
indent,
ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "match_header", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ip_identify_match, match_header));
ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "match_request_uri", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ip_identify_match, match_request_uri));
ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "srv_lookups", "yes", OPT_BOOL_T, 1, FLDSET(struct ip_identify_match, srv_lookups));
- ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "transport", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ip_identify_match, transport));
ast_sorcery_load_object(ast_sip_get_sorcery(), "identify");
ast_sip_register_endpoint_identifier_with_name(&ip_identifier, "ip");
ast_sip_register_endpoint_identifier_with_name(&header_identifier, "header");
ast_sip_register_endpoint_identifier_with_name(&request_identifier, "request_uri");
- ast_sip_register_endpoint_identifier_with_name(&transport_identifier, "transport");
ast_sip_register_endpoint_formatter(&endpoint_identify_formatter);
cli_formatter = ao2_alloc(sizeof(struct ast_sip_cli_formatter_entry), NULL);
ast_sip_unregister_endpoint_identifier(&header_identifier);
ast_sip_unregister_endpoint_identifier(&request_identifier);
ast_sip_unregister_endpoint_identifier(&ip_identifier);
- ast_sip_unregister_endpoint_identifier(&transport_identifier);
return 0;
}