issue #5712
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@7086 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
parent
52da8d9862
commit
766d1a73b1
2 changed files with 32 additions and 11 deletions
|
@ -1,5 +1,7 @@
|
|||
2005-11-11 Kevin P. Fleming <kpfleming@digium.com>
|
||||
|
||||
* channels/chan_sip.c (thread_safe_rand): ensure that threads don't get the same random number (issue #5712)
|
||||
|
||||
* apps/app_voicemail.c (forward_message): correct bugs in message forwarding (issue #5718)
|
||||
(copy_message): use correct path for locking (issue #5704)
|
||||
|
||||
|
|
|
@ -384,6 +384,7 @@ static int global_mwitime = DEFAULT_MWITIME; /*!< Time between MWI checks for pe
|
|||
static int usecnt =0;
|
||||
AST_MUTEX_DEFINE_STATIC(usecnt_lock);
|
||||
|
||||
AST_MUTEX_DEFINE_STATIC(rand_lock);
|
||||
|
||||
/*! \brief Protect the interface list (of sip_pvt's) */
|
||||
AST_MUTEX_DEFINE_STATIC(iflock);
|
||||
|
@ -943,6 +944,24 @@ static const struct ast_channel_tech sip_tech = {
|
|||
.send_text = sip_sendtext,
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief Thread-safe random number generator
|
||||
\return a random number
|
||||
|
||||
This function uses a mutex lock to guarantee that no
|
||||
two threads will receive the same random number.
|
||||
*/
|
||||
static force_inline int thread_safe_rand(void)
|
||||
{
|
||||
int val;
|
||||
|
||||
ast_mutex_lock(&rand_lock);
|
||||
val = rand();
|
||||
ast_mutex_unlock(&rand_lock);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/*! \brief find_sip_method: Find SIP method from header
|
||||
* Strictly speaking, SIP methods are case SENSITIVE, but we don't check
|
||||
* following Jon Postel's rule: Be gentle in what you accept, strict with what you send */
|
||||
|
@ -2721,7 +2740,7 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, char *title)
|
|||
fmt = ast_best_codec(tmp->nativeformats);
|
||||
|
||||
if (title)
|
||||
snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%04x", title, rand() & 0xffff);
|
||||
snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%04x", title, thread_safe_rand() & 0xffff);
|
||||
else if (strchr(i->fromdomain,':'))
|
||||
snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", strchr(i->fromdomain,':')+1, (int)(long)(i));
|
||||
else
|
||||
|
@ -2974,7 +2993,7 @@ static void build_callid(char *callid, int len, struct in_addr ourip, char *from
|
|||
int x;
|
||||
char iabuf[INET_ADDRSTRLEN];
|
||||
for (x=0; x<4; x++) {
|
||||
val = rand();
|
||||
val = thread_safe_rand();
|
||||
res = snprintf(callid, len, "%08x", val);
|
||||
len -= res;
|
||||
callid += res;
|
||||
|
@ -2988,7 +3007,7 @@ static void build_callid(char *callid, int len, struct in_addr ourip, char *from
|
|||
|
||||
static void make_our_tag(char *tagbuf, size_t len)
|
||||
{
|
||||
snprintf(tagbuf, len, "as%08x", rand());
|
||||
snprintf(tagbuf, len, "as%08x", thread_safe_rand());
|
||||
}
|
||||
|
||||
/*! \brief sip_alloc: Allocate SIP_PVT structure and set defaults ---*/
|
||||
|
@ -3021,7 +3040,7 @@ static struct sip_pvt *sip_alloc(char *callid, struct sockaddr_in *sin, int useg
|
|||
memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
|
||||
}
|
||||
|
||||
p->branch = rand();
|
||||
p->branch = thread_safe_rand();
|
||||
make_our_tag(p->tag, sizeof(p->tag));
|
||||
/* Start with 101 instead of 1 */
|
||||
p->ocseq = 101;
|
||||
|
@ -4009,7 +4028,7 @@ static int reqprep(struct sip_request *req, struct sip_pvt *p, int sipmethod, in
|
|||
}
|
||||
|
||||
if (newbranch) {
|
||||
p->branch ^= rand();
|
||||
p->branch ^= thread_safe_rand();
|
||||
build_via(p, p->via, sizeof(p->via));
|
||||
}
|
||||
|
||||
|
@ -4826,7 +4845,7 @@ static int transmit_invite(struct sip_pvt *p, int sipmethod, int sdp, int init)
|
|||
req.method = sipmethod;
|
||||
if (init) {
|
||||
/* Bump branch even on initial requests */
|
||||
p->branch ^= rand();
|
||||
p->branch ^= thread_safe_rand();
|
||||
build_via(p, p->via, sizeof(p->via));
|
||||
if (init > 1)
|
||||
initreqprep(&req, p, sipmethod);
|
||||
|
@ -5400,7 +5419,7 @@ static int transmit_register(struct sip_registry *r, int sipmethod, char *auth,
|
|||
snprintf(addr, sizeof(addr), "sip:%s", r->hostname);
|
||||
ast_copy_string(p->uri, addr, sizeof(p->uri));
|
||||
|
||||
p->branch ^= rand();
|
||||
p->branch ^= thread_safe_rand();
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
init_req(&req, sipmethod, addr);
|
||||
|
@ -5670,7 +5689,7 @@ static void reg_source_db(struct sip_peer *peer)
|
|||
/* SIP isn't up yet, so schedule a poke only, pretty soon */
|
||||
if (peer->pokeexpire > -1)
|
||||
ast_sched_del(sched, peer->pokeexpire);
|
||||
peer->pokeexpire = ast_sched_add(sched, rand() % 5000 + 1, sip_poke_peer_s, peer);
|
||||
peer->pokeexpire = ast_sched_add(sched, thread_safe_rand() % 5000 + 1, sip_poke_peer_s, peer);
|
||||
} else
|
||||
sip_poke_peer(peer);
|
||||
if (peer->expire > -1)
|
||||
|
@ -6131,7 +6150,7 @@ static int check_auth(struct sip_pvt *p, struct sip_request *req, char *randdata
|
|||
res = 1;
|
||||
}
|
||||
} else if (ast_strlen_zero(randdata) || ast_strlen_zero(authtoken)) {
|
||||
snprintf(randdata, randlen, "%08x", rand());
|
||||
snprintf(randdata, randlen, "%08x", thread_safe_rand());
|
||||
transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0);
|
||||
/* Schedule auto destroy in 15 seconds */
|
||||
sip_scheddestroy(p, 15000);
|
||||
|
@ -6247,7 +6266,7 @@ static int check_auth(struct sip_pvt *p, struct sip_request *req, char *randdata
|
|||
|
||||
if (wrongnonce) {
|
||||
|
||||
snprintf(randdata, randlen, "%08x", rand());
|
||||
snprintf(randdata, randlen, "%08x", thread_safe_rand());
|
||||
if (ua_hash && !strncasecmp(ua_hash, resp_hash, strlen(resp_hash))) {
|
||||
if (sipdebug)
|
||||
ast_log(LOG_NOTICE, "stale nonce received from '%s'\n", get_header(req, "To"));
|
||||
|
@ -8962,7 +8981,7 @@ static int build_reply_digest(struct sip_pvt *p, int method, char* digest, int d
|
|||
else
|
||||
snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr));
|
||||
|
||||
snprintf(cnonce, sizeof(cnonce), "%08x", rand());
|
||||
snprintf(cnonce, sizeof(cnonce), "%08x", thread_safe_rand());
|
||||
|
||||
/* Check if we have separate auth credentials */
|
||||
if ((auth = find_realm_authentication(authl, p->realm))) {
|
||||
|
|
Loading…
Reference in a new issue