- short-dial: use "302 Moved" to point to target

This commit is contained in:
Thomas Ries
2006-01-01 20:31:55 +00:00
parent 888f998c8d
commit 70c90f0292
9 changed files with 148 additions and 89 deletions
+1
View File
@@ -1,5 +1,6 @@
0.5.12
======
1-Jan-2006: - short-dial: use "302 Moved" to point to target
28-Dec-2005: - Call logging: display FROM & TO for calls.
26-Dec-2005: - Added a short-dial feature ("pi_shortdial_*" config options)
18-Dec-2005: - Grandstream "unregister at startup" works now
+9 -3
View File
@@ -244,13 +244,19 @@ debug_port = 0
#
# Quick Dial (Short Dial)
# ability to define quick dial numbers that can be accessed by
# dialing "*nn" from a local phone. 'nn' corresponds to the entry number
# dialing "*00" from a local phone. '00' corresponds to the entry number
# (pi_shortdial_entry) below. The '*' character can be chosen freely
# (pi_shortdial_akey).
# Note: To call a real number like "*1234" you would have to dial "**1234"
# Note: If this module is enabled, there does NOT exist a way to dial
# a "real" number like *01, siproxd will try to replace it by it's
# quick dial entry.
#
pi_shortdial_enable = 1
pi_shortdial_akey = *
#
# the first character is the "key", the following characters give
# the length of the number string. E.g. "*00" allows qpeed dials
# from *01 to *99. (the number "*100" will be passed through unprocessed)
pi_shortdial_akey = *00
#
# *01 sipphone echo test
pi_shortdial_entry = 17474743246
+90 -71
View File
@@ -40,95 +40,114 @@ static char const ident[]="$Id$";
/* configuration storage */
extern struct siproxd_config configuration;
/* local prototypes */
static int plugin_shortdial_process(sip_ticket_t *ticket);
static int plugin_shortdial_redirect(sip_ticket_t *ticket, int shortcut_no);
/* returns STS_SIP_SENT if processing is to be terminated,
* otherwise STS_SUCCESS (go on with processing) */
/* code (entry point) */
int plugin_shortdial(sip_ticket_t *ticket) {
int sts=STS_SUCCESS;
osip_uri_t *req_url;
int shortcut_no=0;
if (!ticket || !ticket->sipmsg) return STS_FAILURE;
DEBUGC(DBCLASS_PLUGIN,"plugin entered");
/* only deal with outoing calls (outgoing INVITE requests) */
sip_find_direction(ticket, NULL);
if ((ticket->direction == DIR_OUTGOING) ||
(MSG_IS_INVITE(ticket->sipmsg))) {
/* To header with username must exist, max of 2 characters */
if (ticket && ticket->sipmsg && ticket->sipmsg &&
ticket->sipmsg->to && ticket->sipmsg->to->url &&
ticket->sipmsg->to->url->username &&
(strlen(ticket->sipmsg->to->url->username) >= 2) &&
configuration.pi_shortdial_akey) {
char digit1=ticket->sipmsg->to->url->username[0];
/* check for "activation key" - 1st character in number dialled */
if (digit1 == configuration.pi_shortdial_akey[0]) {
DEBUGC(DBCLASS_PLUGIN,"processing");
plugin_shortdial_process(ticket);
}
}
}
DEBUGC(DBCLASS_PLUGIN,"plugin left");
return STS_SUCCESS;
}
/* private code */
static int plugin_shortdial_process(sip_ticket_t *ticket) {
osip_uri_t *to_url=ticket->sipmsg->to->url;
osip_uri_t *req_url;
char *to_user=to_url->username;
char *new_to_user=NULL;
int shortcut_no=0;
int i, len;
DEBUGC(DBCLASS_PLUGIN,"process: username=[%s]", to_user);
req_url=osip_message_get_uri(ticket->sipmsg);
/* escaped akey? (if it appears twice: e.g. "**1234" -> "*1234") */
if (to_user[1] == configuration.pi_shortdial_akey[0]) {
/* shift left the whole string for 1 position (incl \0 termination)*/
for (i=0; i<strlen(to_user); i++) {
to_user[i]=to_user[i+1];
}
/* only outgoing direction is handled */
sip_find_direction(ticket, NULL);
if (ticket->direction != DIR_OUTGOING)
return STS_SUCCESS;
}
/* extract number */
shortcut_no = atoi(&(to_user[1]));
/* only INVITE and ACK are handled */
if (!MSG_IS_INVITE(ticket->sipmsg) && !MSG_IS_ACK(ticket->sipmsg))
return STS_SUCCESS;
/* REQ URI with username must exist, length as defined in config,
* shortdial must be enabled and short dial key must match */
if (!req_url || !req_url->username ||
!configuration.pi_shortdial_akey ||
(strlen(req_url->username) != strlen(configuration.pi_shortdial_akey)) ||
(req_url->username[0] != configuration.pi_shortdial_akey[0]))
return STS_SUCCESS; /* ignore */
shortcut_no = atoi(&(req_url->username[1]));
if (shortcut_no <= 0) return STS_SUCCESS; /* not a number */
/* requested number is not defined */
/* requested number is not defined (out of range) */
if (shortcut_no > configuration.pi_shortdial_entry.used) {
INFO ("shortdial: requested shortcut %i > available shortcuts",
DEBUGC(DBCLASS_PLUGIN, "shortdial: shortcut %i > available shortcuts",
shortcut_no, configuration.pi_shortdial_entry.used);
return STS_SUCCESS;
}
/* actual replacement INVITE and To header */
new_to_user=configuration.pi_shortdial_entry.string[shortcut_no-1];
if (new_to_user) {
DEBUGC(DBCLASS_PLUGIN,"process: rewriting [%s]->[%s]",
to_user, new_to_user);
len=strlen(new_to_user)+1; /* include trailing "\0" */
/* Request URI */
if (req_url && req_url->username) {
osip_free(req_url->username);
req_url->username=osip_malloc(len);
strncpy(req_url->username, new_to_user, len);
}
/* To header */
to_user=NULL;
osip_free(to_url->username);
to_url->username=osip_malloc(len);
strncpy(to_url->username, new_to_user, len);
/* requested number is not defined (empty) */
if (!configuration.pi_shortdial_entry.string[shortcut_no-1]) {
DEBUGC(DBCLASS_PLUGIN, "shortdial: shortcut %i empty", shortcut_no);
return STS_SUCCESS;
}
/* done */
return STS_SUCCESS;
/*
* called number does match the short dial specification
*/
/* outgoing INVITE request */
if (MSG_IS_INVITE(ticket->sipmsg)) {
DEBUGC(DBCLASS_PLUGIN,"processing INVITE");
sts=plugin_shortdial_redirect(ticket, shortcut_no);
}
/* outgoing ACK request: is result of a local 3xx answer (moved...) */
else if (MSG_IS_ACK(ticket->sipmsg)) {
/* make sure we only catch ACKs caused by myself (**02 -> *02 legitime) */
DEBUGC(DBCLASS_PLUGIN,"processing ACK");
sts=STS_SIP_SENT; /* eat up the ACK that was directed to myself */
}
return sts;
}
/* private code */
static int plugin_shortdial_redirect(sip_ticket_t *ticket, int shortcut_no) {
osip_uri_t *to_url=ticket->sipmsg->to->url;
char *to_user=to_url->username;
char *new_to_user=NULL;
int i, len;
osip_contact_t *contact = NULL;
new_to_user=configuration.pi_shortdial_entry.string[shortcut_no-1];
if (!new_to_user) return STS_SUCCESS;
DEBUGC(DBCLASS_PLUGIN,"redirect: redirecting [%s]->[%s]",
to_user, new_to_user);
len=strlen(new_to_user)+1; /* include trailing "\0" */
/* use a "302 Moved temporarily" response back to the client */
/* new target is within the Contact Header */
/* remove all Contact headers in message */
for (i=0; (contact != NULL) || (i == 0); i++) {
osip_message_get_contact(ticket->sipmsg, 0, &contact);
if (contact) {
osip_list_remove(ticket->sipmsg->contacts,0);
osip_contact_free(contact);
}
} /* for i */
/* insert one new Contact header containing the new target address */
osip_contact_init(&contact);
osip_uri_clone(to_url, &contact->url);
osip_free(contact->url->username);
contact->url->username=osip_malloc(len);
strcpy(contact->url->username, new_to_user);
osip_list_add(ticket->sipmsg->contacts,contact,0);
/* sent redirect message back to local client */
sip_gen_response(ticket, 302 /*Moved temporarily*/);
return STS_SIP_SENT;
}
+17 -11
View File
@@ -110,6 +110,7 @@ int proxy_request (sip_ticket_t *ticket) {
/*
* logging of passing calls
*/
/*&&&& this should be moved to its own loggin plugin */
if (configuration.log_calls) {
osip_uri_t *from_url = NULL;
osip_uri_t *to_url = NULL;
@@ -117,12 +118,13 @@ int proxy_request (sip_ticket_t *ticket) {
char *to_host = NULL;
char *from_username =NULL;
char *from_host = NULL;
char *call_type = NULL;
/* From: 1st preference is contact header, then use From field */
if (!osip_list_eol(request->contacts, 0)) {
from_url = ((osip_contact_t*)(request->contacts->node->element))->url;
} else {
/* From: 1st preference is From header, then try contact header */
if (request->from->url) {
from_url = request->from->url;
} else {
from_url = (osip_uri_t *)osip_list_get(request->contacts, 0);
}
to_url = request->to->url;
@@ -139,20 +141,24 @@ int proxy_request (sip_ticket_t *ticket) {
/* INVITE */
if (MSG_IS_INVITE(request)) {
INFO("%s Call: %s@%s -> %s@%s",
(type==REQTYP_INCOMING) ? "Incoming":"Outgoing",
from_username ? from_username: "*NULL*",
from_host ? from_host : "*NULL*",
to_username ? to_username : "*NULL*",
to_host ? to_host : "*NULL*");
if (type==REQTYP_INCOMING) call_type="Incoming";
else call_type="Outgoing";
/* BYE / CANCEL */
} else if (MSG_IS_ACK(request)) {
call_type="ACK";
} else if (MSG_IS_BYE(request) || MSG_IS_CANCEL(request)) {
INFO("Ending Call: %s@%s -> %s@%s",
call_type="Ending";
}
if (call_type) {
INFO("%s Call: %s@%s -> %s@%s",
call_type,
from_username ? from_username: "*NULL*",
from_host ? from_host : "*NULL*",
to_username ? to_username : "*NULL*",
to_host ? to_host : "*NULL*");
}
} /* log_calls */
+1 -1
View File
@@ -256,7 +256,7 @@ int register_client(sip_ticket_t *ticket, int force_lcl_masq) {
/* answer the request myself. Most likely this is an UNREGISTER
* request when the client just booted */
sts = register_response(ticket, STS_SUCCESS);
return STS_RESP_SENT;
return STS_SIP_SENT;
}
return STS_SUCCESS;
+17 -1
View File
@@ -97,7 +97,23 @@ int security_check_raw(char *sip_buffer, int size) {
DEBUGC(DBCLASS_SIP,"security_check_raw: found only one space");
return STS_FAILURE;
}
/* libosip2 can be put into an endless loop by trying to parse:
---BUFFER DUMP follows---
49 4e 56 49 54 45 20 20 53 49 50 2f 32 2e 30 0d INVITE SIP/2.0.
0a 56 69 61 3a 20 53 49 50 2f 32 2e 30 2f 55 44 .Via: SIP/2.0/UD
Note, this is an INVITE with no valid SIP URI (INVITE SIP/2.0)
*/
/* clumsy... */
if (size >20) {
if (strncmp(sip_buffer, "INVITE SIP/2.0", 15)==0) return STS_FAILURE;
else if (strncmp(sip_buffer, "ACK SIP/2.0", 12)==0) return STS_FAILURE;
else if (strncmp(sip_buffer, "BYE SIP/2.0", 12)==0) return STS_FAILURE;
else if (strncmp(sip_buffer, "CANCEL SIP/2.0", 15)==0) return STS_FAILURE;
else if (strncmp(sip_buffer, "REGISTER SIP/2.0",17)==0) return STS_FAILURE;
else if (strncmp(sip_buffer, "OPTIONS SIP/2.0", 16)==0) return STS_FAILURE;
else if (strncmp(sip_buffer, "INFO SIP/2.0", 13)==0) return STS_FAILURE;
}
/* TODO: still way to go here ... */
return STS_SUCCESS;
+8
View File
@@ -84,6 +84,14 @@ osip_message_t *msg_make_template_reply (sip_ticket_t *ticket, int code) {
osip_to_clone (request->to, &response->to);
osip_from_clone (request->from, &response->from);
/* if 3xx, also include 1st contact header */
if ((code>=300) && (code<400)) {
osip_contact_t *req_contact = NULL;
osip_contact_t *res_contact = NULL;
osip_message_get_contact(request, 0, &req_contact);
osip_contact_clone (req_contact, &res_contact);
osip_list_add(response->contacts,res_contact,0);
}
/* via headers */
pos = 0;
+4 -1
View File
@@ -426,7 +426,10 @@ int main (int argc, char *argv[])
* additional preprocessing
*********************************/
/* Dial shortcuts */
if (configuration.pi_shortdial) plugin_shortdial(&ticket);
if (configuration.pi_shortdial) {
sts = plugin_shortdial(&ticket);
if (sts == STS_SIP_SENT) goto end_loop;
}
/*********************************
+1 -1
View File
@@ -262,7 +262,7 @@ int sip_message_set_body(osip_message_t * sip, const char *buf, int len);
#define STS_FAILURE 1 /* FAILURE */
#define STS_FALSE 1 /* FALSE */
#define STS_NEED_AUTH 1001 /* need authentication */
#define STS_RESP_SENT 2001 /* response is already sent */
#define STS_SIP_SENT 2001 /* SIP packet is already sent */
/* symbolic direction of data */
#define DIR_INCOMING 1