Add --remote-nat-sip --remote-nat-rtp

This commit is contained in:
Andreas Eversberg 2021-09-14 15:06:42 +02:00
parent 95fdc4d6da
commit 4cdc6437a6
3 changed files with 82 additions and 18 deletions

View File

@ -43,6 +43,8 @@ const char *remote_peer = NULL;
const char *asserted_id = NULL;
int local_register = 0;
int remote_register = 0;
int remote_nat_sip = 0;
int remote_nat_rtp = 0;
const char *register_user = NULL;
const char *register_peer = NULL;
int local_auth = 0;
@ -105,6 +107,12 @@ static void print_help()
printf(" Define, if we must register to a registrar.\n");
printf(" If '--register' was given, but not any of '--local-register' or\n");
printf(" '--remote-register', remote registration automatically used.\n");
printf(" --remote-nat-sip\n");
printf(" Ignore the address+port from the SIP contact. Use the address+port from\n");
printf(" where the SIP massasge was sent.\n");
printf(" --remote-nat-rtp\n");
printf(" Ignore the RTP address from the SDP message. Use the RTP address from\n");
printf(" the remote peer. (untested!)\n");
printf(" -A --auth <user> <password> <realm>\n");
printf(" Define, if we must perform authentication.\n");
printf(" Realm can be set to anything. It is relevant for local authentication.\n");
@ -135,12 +143,14 @@ static void print_help()
#define OPT_RECEIVE_NER 257
#define OPT_LOCAL_REG 258
#define OPT_REMOTE_REG 259
#define OPT_LOCAL_AUTH 260
#define OPT_REMOTE_AUTH 261
#define OPT_REG_INTER 262
#define OPT_OPT_INTER 263
#define OPT_STUN_INTER 264
#define OPT_EXPIRES 265
#define OPT_REMOTE_SIP 260
#define OPT_REMOTE_RTP 261
#define OPT_LOCAL_AUTH 262
#define OPT_REMOTE_AUTH 263
#define OPT_REG_INTER 264
#define OPT_OPT_INTER 265
#define OPT_STUN_INTER 266
#define OPT_EXPIRES 267
static void add_options(void)
{
@ -156,6 +166,8 @@ static void add_options(void)
option_add('R', "register", 1);
option_add(OPT_LOCAL_REG, "local-register", 0);
option_add(OPT_REMOTE_REG, "remote-register", 0);
option_add(OPT_REMOTE_SIP, "remote-nat-sip", 0);
option_add(OPT_REMOTE_RTP, "remote-nat-rtp", 0);
option_add('A', "auth", 3);
option_add(OPT_LOCAL_AUTH, "local-auth", 0);
option_add(OPT_REMOTE_AUTH, "remote-auth", 0);
@ -237,6 +249,12 @@ static int handle_options(int short_option, int argi, char **argv)
case OPT_REMOTE_REG:
remote_register = 1;
break;
case OPT_REMOTE_SIP:
remote_nat_sip = 1;
break;
case OPT_REMOTE_RTP:
remote_nat_rtp = 1;
break;
case 'A':
auth_user = options_strdup(argv[argi]);
auth_password = options_strdup(argv[argi + 1]);
@ -336,7 +354,7 @@ int main(int argc, char *argv[])
}
if (!cc_argc || !!strncasecmp(cc_argv[0], "help", 4)) {
sip_ep = sip_endpoint_create(user_agent, send_no_ringing_after_progress, receive_no_ringing_after_progress, name, local_user, local_peer, remote_user, remote_peer, asserted_id, local_register, remote_register, register_user, register_peer, local_auth, remote_auth, auth_user, auth_password, auth_realm, public_ip, stun_server, register_interval, options_interval, stun_interval, expires);
sip_ep = sip_endpoint_create(user_agent, send_no_ringing_after_progress, receive_no_ringing_after_progress, name, local_user, local_peer, remote_user, remote_peer, asserted_id, local_register, remote_register, remote_nat_sip, remote_nat_rtp, register_user, register_peer, local_auth, remote_auth, auth_user, auth_password, auth_realm, public_ip, stun_server, register_interval, options_interval, stun_interval, expires);
if (!sip_ep) {
PDEBUG(DSIP, DEBUG_ERROR, "SIP initializing failed!\n");
goto error;

View File

@ -30,6 +30,7 @@
#include <sofia-sip/sip_header.h>
#include <sofia-sip/stun_tag.h>
#include <sofia-sip/su_md5.h>
#include <sofia-sip/msg_addr.h>
#include "sip.h"
#ifndef SOFIA_SIP_GCC_4_8_PATCH_APLLIED
@ -167,6 +168,23 @@ static const char *sdp_replace_contact(const char *input, const char *address)
return sdp;
}
void rtp_peer_nat(sip_endpoint_t *sip_ep, char **sdp_p)
{
if (sip_ep->remote_nat_rtp && sip_ep->remote_peer[0]) {
/* replace peer by remote contact, note that port in peer is ignored */
char peer[256], *p;
strcpy(peer, sip_ep->remote_contact_peer);
p = strchr(peer, ':');
if (*p)
*p = '\0';
const char *s = sdp_replace_contact(*sdp_p, peer);
free(*sdp_p);
*sdp_p = malloc(strlen(s) + 1);
memcpy(*sdp_p, s, strlen(s));
(*sdp_p)[strlen(s)] = '\0';
}
}
/* authenticate (remote) */
static int authenticate(sip_endpoint_t *sip_ep, nua_handle_t *nh, sip_t const *sip)
{
@ -510,8 +528,10 @@ static void setup_req(call_t *call, osmo_cc_msg_t *msg)
// contact is set above
/* append port of local peer */
p = osmo_cc_port_of_address(call->sip_ep->local_peer);
if (p)
if (p) {
strcat(contact, ":");
strcat(contact, p);
}
PDEBUG(DSIP, DEBUG_DEBUG, " -> Contact = %s\n", contact);
}
@ -879,13 +899,28 @@ static void ep_i_register(sip_endpoint_t *sip_ep, int status, nua_t *nua, nua_ha
if (sip->sip_contact->m_url->url_user)
strcpy(contact_user, sip->sip_contact->m_url->url_user);
if (sip->sip_contact->m_url->url_host) {
// FIXME: unstable/might not work with IPv6
strcpy(contact_peer, sip->sip_contact->m_url->url_host);
if (sip->sip_contact->m_url->url_port && sip->sip_contact->m_url->url_port[0]) {
strcat(contact_peer, ":");
strcat(contact_peer, sip->sip_contact->m_url->url_port);
if (sip_ep->remote_nat_sip) {
su_addrinfo_t *addrinfo = msg_addrinfo(data->e_msg);
getnameinfo(addrinfo->ai_addr, (socklen_t)addrinfo->ai_addrlen, contact_peer, sizeof(contact_peer), NULL, 0, NI_NUMERICHOST);
switch (addrinfo->ai_addr->sa_family) {
case AF_INET:
sprintf(strchr(contact_peer, '\0'), ":%d", ntohs(((struct sockaddr_in *) addrinfo->ai_addr)->sin_port));
break;
case AF_INET6:
sprintf(strchr(contact_peer, '\0'), ":%d", ntohs(((struct sockaddr_in6 *) addrinfo->ai_addr)->sin6_port));
break;
}
PDEBUG(DSIP, DEBUG_DEBUG, " -> contact %s@%s (given by UDP source)\n", contact_user, contact_peer);
} else {
if (sip->sip_contact->m_url->url_host) {
// FIXME: unstable/might not work with IPv6
strcpy(contact_peer, sip->sip_contact->m_url->url_host);
if (sip->sip_contact->m_url->url_port && sip->sip_contact->m_url->url_port[0]) {
strcat(contact_peer, ":");
strcat(contact_peer, sip->sip_contact->m_url->url_port);
}
}
PDEBUG(DSIP, DEBUG_DEBUG, " -> contact %s@%s (given by remote)\n", contact_user, contact_peer);
}
if (!sip_ep->local_register) {
@ -899,8 +934,6 @@ static void ep_i_register(sip_endpoint_t *sip_ep, int status, nua_t *nua, nua_ha
return;
}
PDEBUG(DSIP, DEBUG_DEBUG, " -> contact %s@%s\n", contact_user, contact_peer);
if (sip_ep->authenticate_local && sip_ep->auth_realm[0]) {
authorization = sip->sip_authorization;
status = check_authorization(authorization, "REGISTER", sip_ep->auth_user, sip_ep->auth_password, sip_ep->auth_realm, sip_ep->register_nonce, &auth_text);
@ -1079,6 +1112,7 @@ static void call_i_invite(call_t *call, nua_handle_t *nh, sip_t const *sip)
call->sdp_request = malloc(sip->sip_payload->pl_len + 1);
memcpy(call->sdp_request, sip->sip_payload->pl_data, sip->sip_payload->pl_len);
call->sdp_request[sip->sip_payload->pl_len] = '\0';
rtp_peer_nat(call->sip_ep, &call->sdp_request);
} else {
PDEBUG(DSIP, DEBUG_DEBUG, " -> No SDP in message\n");
new_state(call, SIP_STATE_IN_INVITE);
@ -1183,6 +1217,7 @@ static void call_r_invite(call_t *call, int status, char const *phrase, nua_hand
call->sdp_response = malloc(sip->sip_payload->pl_len + 1);
memcpy(call->sdp_response, sip->sip_payload->pl_data, sip->sip_payload->pl_len);
call->sdp_response[sip->sip_payload->pl_len] = '\0';
rtp_peer_nat(call->sip_ep, &call->sdp_response);
osmo_cc_debug_sdp(call->sdp_response);
} else if (!call->sdp_response && status >= 200 && status <= 299) {
PDEBUG(DSIP, DEBUG_DEBUG, " -> No SDP in message\n");
@ -1580,6 +1615,12 @@ static void sip_message(nua_event_t event, int status, char const *phrase, nua_t
case nua_i_terminated:
PDEBUG(DSIP, DEBUG_DEBUG, "terminated received\n");
break;
case nua_i_prack:
PDEBUG(DSIP, DEBUG_DEBUG, "prack indication received\n");
break;
case nua_r_prack:
PDEBUG(DSIP, DEBUG_DEBUG, "prack response received\n");
break;
default:
PDEBUG(DSIP, DEBUG_DEBUG, "Event %d not handled\n", event);
}
@ -1671,7 +1712,7 @@ static void register_option_timeout(struct timer *timer)
TAG_END());
}
sip_endpoint_t *sip_endpoint_create(const char *user_agent, int send_no_ringing_after_progress, int receive_no_ringing_after_progress, const char *name, const char *local_user, const char *local_peer, const char *remote_user, const char *remote_peer, const char *asserted_id, int local_register, int remote_register, const char *register_user, const char *register_peer, int authenticate_local, int authenticate_remote, const char *auth_user, const char *auth_password, const char *auth_realm, const char *public_ip, const char *stun_server, int register_interval, int options_interval, int stun_interval, int expires)
sip_endpoint_t *sip_endpoint_create(const char *user_agent, int send_no_ringing_after_progress, int receive_no_ringing_after_progress, const char *name, const char *local_user, const char *local_peer, const char *remote_user, const char *remote_peer, const char *asserted_id, int local_register, int remote_register, int remote_nat_sip, int remote_nat_rtp, const char *register_user, const char *register_peer, int authenticate_local, int authenticate_remote, const char *auth_user, const char *auth_password, const char *auth_realm, const char *public_ip, const char *stun_server, int register_interval, int options_interval, int stun_interval, int expires)
{
sip_endpoint_t *sip_ep;
char local[256];
@ -1696,6 +1737,8 @@ sip_endpoint_t *sip_endpoint_create(const char *user_agent, int send_no_ringing_
sip_ep->local_register = local_register;
sip_ep->remote_register = remote_register;
sip_ep->remote_nat_sip = remote_nat_sip;
sip_ep->remote_nat_rtp = remote_nat_rtp;
sip_ep->register_user = register_user;
sip_ep->register_peer = register_peer;
@ -1753,6 +1796,7 @@ sip_endpoint_t *sip_endpoint_create(const char *user_agent, int send_no_ringing_
NUTAG_AUTOANSWER(0),
TAG_IF(expires, NUTAG_SESSION_TIMER(expires)),
// wozu das? NUTAG_ALLOW("INFO"),
NUTAG_ALLOW("PRACK"),
TAG_NULL());
if (sip_ep->remote_register)

View File

@ -51,6 +51,8 @@ typedef struct sip_endpoint {
const char *asserted_id;
int local_register;
int remote_register;
int remote_nat_sip;
int remote_nat_rtp;
const char *register_user;
const char *register_peer;
int authenticate_local;
@ -109,7 +111,7 @@ typedef struct sip_call {
} call_t;
void cc_message(osmo_cc_endpoint_t *ep, uint32_t callref, osmo_cc_msg_t *msg);
sip_endpoint_t *sip_endpoint_create(const char *user_agent, int send_no_ringing_after_progress, int receive_no_ringing_after_progress, const char *name, const char *local_user, const char *local_peer, const char *remote_user, const char *remote_peer, const char *asserted_id, int local_register, int remote_register, const char *register_user, const char *register_peer, int authenticate_local, int authenticate_remote, const char *auth_user, const char *auth_password, const char *auth_realm, const char *public_ip, const char *stun_server, int register_interval, int options_interval, int stun_interval, int expires);
sip_endpoint_t *sip_endpoint_create(const char *user_agent, int send_no_ringing_after_progress, int receive_no_ringing_after_progress, const char *name, const char *local_user, const char *local_peer, const char *remote_user, const char *remote_peer, const char *asserted_id, int local_register, int remote_register, int remote_nat_sip, int remote_nat_rtp, const char *register_user, const char *register_peer, int authenticate_local, int authenticate_remote, const char *auth_user, const char *auth_password, const char *auth_realm, const char *public_ip, const char *stun_server, int register_interval, int options_interval, int stun_interval, int expires);
void sip_endpoint_destroy(sip_endpoint_t *sip_ep);
int sip_init(int debug_level);
void sip_exit(void);