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
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);
"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)"},
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;
{
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;
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);
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;
if (inst->options_timeout)
schedule_timer(&p_s_invite_option_timer, inst->options_timeout, 0);
- /* process 1xx */
switch (status) {
case 100:
#if 0
}
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);
}
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;
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;
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());
}
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);
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");
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:
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);
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);