[svn-commits] branch oej/sipregister r8836 -
/team/oej/sipregister/channels/chan_sip.c
svn-commits at lists.digium.com
svn-commits at lists.digium.com
Sat Jan 28 10:44:53 MST 2006
Author: oej
Date: Sat Jan 28 11:44:51 2006
New Revision: 8836
URL: http://svn.digium.com/view/asterisk?rev=8836&view=rev
Log:
First stab at fixing multiple outbound registrations to the same host.
We now send a magic random string to the host as contact. On inbound call,
we recognize the string and replace it with the extension.
Todo: Add initialization of peer that contained the register= line.
So we don't match on IP on incoming calls.
Modified:
team/oej/sipregister/channels/chan_sip.c
Modified: team/oej/sipregister/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/sipregister/channels/chan_sip.c?rev=8836&r1=8835&r2=8836&view=diff
==============================================================================
--- team/oej/sipregister/channels/chan_sip.c (original)
+++ team/oej/sipregister/channels/chan_sip.c Sat Jan 28 11:44:51 2006
@@ -133,6 +133,8 @@
static int max_expiry = DEFAULT_MAX_EXPIRY; /*!< Maximum accepted registration time */
static int default_expiry = DEFAULT_DEFAULT_EXPIRY;
static int expiry = DEFAULT_EXPIRY;
+
+#define REG_MAGICMARKER "ASTZVXW" /*!< Magic marker for outbound registrations */
#ifndef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b))
@@ -697,7 +699,8 @@
struct ast_dsp *vad; /*!< Voice Activation Detection dsp */
struct sip_peer *peerpoke; /*!< If this dialog is to poke a peer, which one */
- struct sip_registry *registry; /*!< If this is a REGISTER dialog, to which registry */
+ struct sip_registry *registry; /*!< If this is a REGISTER dialog, to which registry
+ If this is an INVITE, to which registry */
struct ast_rtp *rtp; /*!< RTP Session */
struct ast_rtp *vrtp; /*!< Video RTP session */
struct sip_pkt *packets; /*!< Packets scheduled for re-transmission */
@@ -837,7 +840,8 @@
AST_STRING_FIELD(hostname); /*!< Domain or host we register to */
AST_STRING_FIELD(secret); /*!< Password in clear text */
AST_STRING_FIELD(md5secret); /*!< Password in md5 */
- AST_STRING_FIELD(contact); /*!< Contact extension */
+ AST_STRING_FIELD(contact); /*!< Contact used for this registry entry */
+ AST_STRING_FIELD(extension); /*!< Extension to place incoming calls to */
AST_STRING_FIELD(random);
);
int portno; /*!< Optional port override */
@@ -852,6 +856,7 @@
struct sockaddr_in us; /*!< Who the server thinks we are */
int noncecount; /*!< Nonce-count */
char lastmsg[256]; /*!< Last Message sent/received */
+ struct sip_peer *peer; /*!< If we ahve a known peer for this registry entry, use it for incoming calls */
};
/* --- Linked lists of various objects --------*/
@@ -950,6 +955,7 @@
static int sip_poke_peer(struct sip_peer *peer);
static int __sip_do_register(struct sip_registry *r);
static int restart_monitor(void);
+static char *generate_random_string(char *buf, size_t size);
/*! \brief Definition of this channel for PBX channel registration */
static const struct ast_channel_tech sip_tech = {
@@ -3300,9 +3306,10 @@
{
struct sip_registry *reg;
char username[256];
- char *hostname=NULL, *secret=NULL, *authuser=NULL;
- char *porta=NULL;
- char *contact=NULL;
+ char randomcontact[33];
+ char *hostname = NULL, *secret = NULL, *authuser = NULL;
+ char *porta = NULL;
+ char *extension = NULL;
int portnum = 0;
if (peer) { /* build string from peer info */
@@ -3319,7 +3326,7 @@
*hostname++ = '\0';
if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) {
ast_log(LOG_WARNING, "Format for registration is %s at line %d\n",
- "user[:secret[:authuser]]@host[:port][/contact]",
+ "user[:secret[:authuser]]@host[:port][/extension]",
lineno);
return -1;
}
@@ -3332,11 +3339,11 @@
*authuser++ = '\0';
}
/* split host[:port][/contact] */
- contact = strchr(hostname, '/');
- if (contact)
- *contact++ = '\0';
- if (ast_strlen_zero(contact))
- contact = "s";
+ extension = strchr(hostname, '/');
+ if (extension)
+ *extension++ = '\0';
+ if (ast_strlen_zero(extension))
+ extension = "s";
porta = strchr(hostname, ':');
if (porta) {
*porta++ = '\0';
@@ -3351,6 +3358,8 @@
ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n");
return -1;
}
+ if (peer)
+ reg->peer = (struct sip_peer * ) peer; /* Save SIP peer binding for incoming calls */
if (ast_string_field_init(reg)) {
ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n");
@@ -3360,7 +3369,6 @@
regobjs++;
ASTOBJ_INIT(reg);
- ast_string_field_set(reg, contact, contact);
if (username)
ast_string_field_set(reg, username, username);
if (hostname)
@@ -3369,13 +3377,20 @@
ast_string_field_set(reg, authuser, authuser);
if (secret)
ast_string_field_set(reg, secret, secret);
+
+ ast_string_field_set(reg, extension, extension);
+
+ /* Build a random contact string for this registration entry */
+ generate_random_string(randomcontact, sizeof(randomcontact));
+ ast_string_field_build(reg, contact, "%s-%s", REG_MAGICMARKER, randomcontact);
+
reg->expire = -1;
reg->timeout = -1;
reg->refresh = default_expiry;
reg->portno = portnum;
reg->callid_valid = 0;
reg->ocseq = 101;
- ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */
+ ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */
ASTOBJ_UNREF(reg,sip_registry_destroy);
return 0;
}
@@ -5406,7 +5421,7 @@
} else {
r->regstate = REG_STATE_UNREGISTERED;
r->timeout = -1;
- res=transmit_register(r, SIP_REGISTER, NULL, NULL);
+ res = transmit_register(r, SIP_REGISTER, NULL, NULL);
}
manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate));
ASTOBJ_UNREF(r, sip_registry_destroy);
@@ -5445,7 +5460,7 @@
r->callid_valid = 1;
}
/* Allocate SIP packet for registration */
- p=sip_alloc( r->callid, NULL, 0, SIP_REGISTER);
+ p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER);
if (!p) {
ast_log(LOG_WARNING, "Unable to allocate registration call\n");
return 0;
@@ -5493,7 +5508,8 @@
}
if (!ast_strlen_zero(r->username))
ast_string_field_set(p, username, r->username);
- /* Save extension in packet */
+
+ /* Save contact in packet */
ast_string_field_set(p, exten, r->contact);
/*
@@ -6617,12 +6633,13 @@
return 0;
}
-/*! \brief Find out who the call is for */
+/*! \brief Find out what extension the call is for */
static int get_destination(struct sip_pvt *p, struct sip_request *oreq)
{
char tmp[256] = "", *uri, *a;
char tmpf[256], *from;
struct sip_request *req;
+ int localdomain = TRUE;
req = oreq;
if (!req)
@@ -6674,12 +6691,13 @@
domain_context[0] = '\0';
if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) {
+ localdomain = FALSE;
if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) {
ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain);
return -2;
}
}
- /* If we have a context defined, overwrite the original context */
+ /* If we have a domain context defined, overwrite the original context */
if (!ast_strlen_zero(domain_context))
ast_string_field_set(p, context, domain_context);
}
@@ -6693,6 +6711,36 @@
} else
ast_string_field_set(p, fromdomain, from);
}
+
+ /* If the URI starts with our magic marker and has a corresponding
+ entry in the registry, then replace the URI with the extension
+ we want to use */
+ /* We don't have to check this at all if we have no registry entries... */
+ if (localdomain && req->method == SIP_INVITE) {
+ if (option_debug)
+ ast_log(LOG_DEBUG, "Checking %s for magic registry marker \n", uri);
+ /* Check if the incoming URI is a registry entry */
+ /* Need a function in ASTOBJ to check if there are objects
+ in the container at all here to avoid this check
+ when we have no registry entries */
+ if (!strncmp(uri, REG_MAGICMARKER, strlen(REG_MAGICMARKER))) {
+ if (option_debug)
+ ast_log(LOG_DEBUG, "Checking for %s in registry\n", uri);
+ /* Traverse the registry to find something */
+ int found = FALSE;
+ ASTOBJ_CONTAINER_TRAVERSE(®l, !found, do {
+ ASTOBJ_RDLOCK(iterator);
+ if (!strcmp(uri, iterator->contact)) {
+ found = TRUE;
+ /* Use the extension of this registry item for the incoming call */
+ uri = (char *) iterator->extension;
+ p->registry = iterator;
+ }
+ ASTOBJ_UNLOCK(iterator);
+ } while(0));
+ }
+ }
+
if (sip_debug_test_pvt(p))
ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain);
@@ -7226,6 +7274,7 @@
if (peer) {
if (debug)
ast_verbose("Found peer '%s'\n", peer->name);
+
/* Take the peer */
ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY);
@@ -10423,6 +10472,7 @@
}
} else if (debug)
ast_verbose("Ignoring this INVITE request\n");
+
if (!p->lastinvite && !ignore && !p->owner) {
/* Handle authentication if this is our first invite */
More information about the svn-commits
mailing list