fixup register
authorAndreas Eversberg <jolly@eversberg.eu>
Sat, 4 Nov 2017 14:32:39 +0000 (15:32 +0100)
committerAndreas Eversberg <jolly@eversberg.eu>
Sat, 4 Nov 2017 14:32:39 +0000 (15:32 +0100)
default/interface.conf
interface.c
interface.h
sip.cpp

index 8593c9f..a29deaf 100644 (file)
 #authenticate <user> <password>
 ## define keepalive timer to keep INVITE/REGISTER alive
 #options-timer 15
-## define stun server and resolving interval
+## define public IP (if behind NAT firewall)
+#public 123.45.67.89
+## OR define stun server and resolving interval
 #stun stun.sipgate.net 300
 ## screen caller ID to SIP caller ID
 #screen-out % <callerID>
index 71e1d80..e730ab8 100644 (file)
@@ -1034,8 +1034,35 @@ static int options_timer(struct interface *interface, char *filename, int line,
                return(-1);
        }
 
-       if (value)
-               interface->sip_options_timer = atoi(value);
+       if (!value || !value[0]) {
+               SPRINT(interface_error, "Error in %s (line %d): Missing timer value.\n", filename, line);
+               return(-1);
+       }
+       interface->sip_options_timer = atoi(value);
+
+       return(0);
+#endif
+}
+static int options_public(struct interface *interface, char *filename, int line, char *parameter, char *value)
+{
+#ifndef WITH_SIP
+       SPRINT(interface_error, "Error in %s (line %d): SIP not compiled in.\n", filename, line);
+       return(-1);
+#else
+       if (!interface->sip) {
+               SPRINT(interface_error, "Error in %s (line %d): This is not a SIP interface.\n", filename, line);
+               return(-1);
+       }
+       if (interface->sip_stun_server[0]) {
+               SPRINT(interface_error, "Error in %s (line %d): Don't specify STUN, if you want to define public IP.\n", filename, line);
+               return(-1);
+       }
+
+       if (!value || !value[0]) {
+               SPRINT(interface_error, "Error in %s (line %d): Missing public IP.\n", filename, line);
+               return(-1);
+       }
+       SCPY(interface->sip_public_ip, value);
 
        return(0);
 #endif
@@ -1052,6 +1079,10 @@ static int options_stun(struct interface *interface, char *filename, int line, c
                SPRINT(interface_error, "Error in %s (line %d): This is not a SIP interface.\n", filename, line);
                return(-1);
        }
+       if (interface->sip_public_ip[0]) {
+               SPRINT(interface_error, "Error in %s (line %d): Don't specify public IP, if you want to define STUN.\n", filename, line);
+               return(-1);
+       }
 
        if (!value || !value[0]) {
                SPRINT(interface_error, "Error in %s (line %d): Missing STUN server.\n", filename, line);
@@ -1507,6 +1538,8 @@ struct interface_param interface_param[] = {
        "Defines SIP user and password for authentication."},
        {"options-timer", &options_timer, "<timer> | 0",
        "Defines SIP timer to send OPTIONS messages to keepalive SIP sessions."},
+       {"public", &options_public, "<server> <interval>",
+       "Defines public IP, if this endpoint is behind NAT firewall."},
        {"stun", &options_stun, "<server> <interval>",
        "Defines STUN server to resolv real local IP.\n"
        "The interval is used to check if IP has changed. (use 300)"},
index 58773bb..e3c6729 100644 (file)
@@ -134,6 +134,7 @@ struct interface {
        char                    sip_register_user[128];
        char                    sip_register_host[128];
        int                     sip_options_timer; /* timer to keepalive invite/register transactions */
+       char                    sip_public_ip[128];
        char                    sip_stun_server[128];
        int                     sip_stun_interval; /* timer to check own IP address */
        void                    *sip_inst; /* sip instance */
diff --git a/sip.cpp b/sip.cpp
index 21309d1..e136579 100644 (file)
--- a/sip.cpp
+++ b/sip.cpp
@@ -66,11 +66,11 @@ struct sip_inst {
        su_root_t               *root;
        nua_t                   *nua;
 
+       char                    public_ip[128];
        int                     stun_state;
        char                    stun_server[128];
        stun_handle_t           *stun_handle;
        su_socket_t             stun_socket;
-       char                    stun_ipaddr[128];
        struct lcr_timer        stun_retry_timer;
        int                     stun_interval;
 
@@ -866,9 +866,9 @@ unsigned int Psip::get_local_ip(unsigned int ip)
 {
        struct sip_inst *inst = (struct sip_inst *) p_s_sip_inst;
 
-       if (inst->stun_handle && inst->stun_ipaddr[0]) {
-               PDEBUG(DEBUG_SIP, "RTP local IP is replaced by STUN ip %s\n", inst->stun_ipaddr);
-               inet_pton(AF_INET, inst->stun_ipaddr, &ip);
+       if (inst->public_ip[0]) {
+               PDEBUG(DEBUG_SIP, "RTP local IP is replaced by STUN ip %s\n", inst->public_ip);
+               inet_pton(AF_INET, inst->public_ip, &ip);
                return htonl(ip);
        }
        return ip;
@@ -1132,8 +1132,8 @@ int Psip::message_setup(unsigned int epoint_id, int message_id, union parameter
 
        SPRINT(from, "sip:%s@%s", p_callerinfo.id, remote);
        SPRINT(to, "sip:%s@%s", p_dialinginfo.id, remote);
-       if (inst->stun_handle && inst->stun_ipaddr[0])
-               SPRINT(contact, "sip:%s@%s", p_callerinfo.id, inst->stun_ipaddr);
+       if (inst->public_ip[0])
+               SPRINT(contact, "sip:%s@%s", p_callerinfo.id, inst->public_ip);
 
        sip_trace_header(this, inst->interface_name, "INVITE", DIRECTION_OUT);
        add_trace("from", "uri", "%s", from);
@@ -1754,8 +1754,6 @@ void Psip::r_cancel(int status, char const *phrase, nua_t *nua, nua_magic_t *mag
        trigger_work(&p_s_delete);
 }
 
-#warning i_invite
-#warning r_invite
 void Psip::r_invite(int status, char const *phrase, nua_t *nua, nua_magic_t *magic, nua_handle_t *nh, nua_hmagic_t *hmagic, sip_t const *sip, tagi_t tagss[])
 {
        struct sip_inst *inst = (struct sip_inst *) p_s_sip_inst;
@@ -1814,7 +1812,6 @@ void Psip::r_invite(int status, char const *phrase, nua_t *nua, nua_magic_t *mag
        if (inst->options_timeout)
                schedule_timer(&p_s_invite_option_timer, inst->options_timeout, 0);
 
-       /* process 1xx */
        switch (status) {
        case 100:
 #if 0
@@ -1844,16 +1841,8 @@ void Psip::r_invite(int status, char const *phrase, nua_t *nua, nua_magic_t *mag
                }
                message_put(message);
                return;
-       default:
-               if (status < 100 || status > 199)
-                       break;
-               PDEBUG(DEBUG_SIP, "skipping 1xx message\n");
-
-               return;
-       }
-
-       /* process 2xx */
-       if (status >= 200 && status <= 299) {
+       case 200:
+               status_200:
                PDEBUG(DEBUG_SIP, "do connect\n");
                nua_ack(nh, TAG_END());
                new_state(PORT_STATE_CONNECT);
@@ -1867,7 +1856,16 @@ void Psip::r_invite(int status, char const *phrase, nua_t *nua, nua_magic_t *mag
                }
                message_put(message);
                return;
+       default:
+               if (status >= 200 && status <= 299)
+                       goto status_200;
+               if (status < 100 || status > 199)
+                       break;
+               PDEBUG(DEBUG_SIP, "skipping 1xx message\n");
+
+               return;
        }
+
        cause = status2cause(status);
        location = LOCATION_BEYOND;
 
@@ -1899,7 +1897,7 @@ void Psip::r_options(int status, char const *phrase, nua_t *nua, nua_magic_t *ma
 
        PDEBUG(DEBUG_SIP, "options result %d received\n", status);
 
-       if (status == 200) {
+       if (status >= 200 && status <= 299) {
                PDEBUG(DEBUG_SIP, "options ok, scheduling timer\n");
                schedule_timer(&p_s_invite_option_timer, inst->options_timeout, 0);
                return;
@@ -1977,7 +1975,6 @@ static void challenge(struct sip_inst *inst, class Psip *psip, int status, char
        add_trace("pass", NULL, "%s", inst->auth_password);
        end_trace();
 
-#warning hier als option
        nua_authenticate(nh, /*SIPTAG_EXPIRES_STR("3600"),*/ NUTAG_AUTH(authentication), TAG_END());
 }
 
@@ -1999,6 +1996,7 @@ static void sip_callback(nua_event_t event, int status, char const *phrase, nua_
 
                switch (status) {
                case 200:
+                       status_200:
                        inst->register_state = REGISTER_STATE_REGISTERED;
                        if (inst->options_timeout)
                                schedule_timer(&inst->register_option_timer, inst->options_timeout, 0);
@@ -2009,6 +2007,8 @@ static void sip_callback(nua_event_t event, int status, char const *phrase, nua_
                        challenge(inst, NULL, status, phrase, nua, magic, nh, hmagic, sip, tags);
                        break;
                default:
+                       if (status >= 200 && status <= 299)
+                               goto status_200;
                        if (status < 400)
                                break;
                        PDEBUG(DEBUG_SIP, "Register failed, starting register timer\n");
@@ -2136,11 +2136,11 @@ static void stun_bind_cb(stun_discovery_magic_t *magic, stun_handle_t *sh, stun_
                        PDEBUG(DEBUG_SIP, "stun_discovery_get_address failed\n");
                        goto failed;
                }
-               su_inet_ntop(sa.su_family, SU_ADDR(&sa), inst->stun_ipaddr, sizeof(inst->stun_ipaddr));
+               su_inet_ntop(sa.su_family, SU_ADDR(&sa), inst->public_ip, sizeof(inst->public_ip));
                inst->stun_state = STUN_STATE_RESOLVED;
                schedule_timer(&inst->stun_retry_timer, inst->stun_interval, 0);
                sip_trace_header(NULL, inst->interface_name, "STUN resolved", DIRECTION_OUT);
-               add_trace("ip", "addr", "%s", inst->stun_ipaddr);
+               add_trace("ip", "addr", "%s", inst->public_ip);
                end_trace();
                break;
        default:
@@ -2298,6 +2298,7 @@ int sip_init_inst(struct interface *interface)
                NUTAG_AUTOANSWER(0),
                TAG_NULL());
 
+       SCPY(inst->public_ip, interface->sip_public_ip);
        if (interface->sip_stun_server[0]) {
 #if 0
                inst->stun_root = su_root_create(inst);
@@ -2453,8 +2454,8 @@ static void sip_handle_register(struct sip_inst *inst)
 
                SPRINT(from, "sip:%s@%s", inst->register_user, inst->register_host);
                SPRINT(to, "sip:%s@%s", inst->register_user, inst->register_host);
-               if (inst->stun_handle && inst->stun_ipaddr[0])
-                       SPRINT(contact, "sip:%s@%s", inst->register_user, inst->stun_ipaddr);
+               if (inst->public_ip[0])
+                       SPRINT(contact, "sip:%s@%s", inst->register_user, inst->public_ip);
 
                sip_trace_header(NULL, inst->interface_name, "REGISTER", DIRECTION_OUT);
                add_trace("from", "uri", "%s", from);