mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-16 23:08:32 +00:00
Merge SIP/MySQL friends patch
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@2053 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
OSARCH=$(shell uname -s)
|
OSARCH=$(shell uname -s)
|
||||||
|
|
||||||
USE_MYSQL_FRIENDS=0
|
USE_MYSQL_FRIENDS=1
|
||||||
|
|
||||||
CHANNEL_LIBS=chan_modem.so chan_iax.so chan_sip.so \
|
CHANNEL_LIBS=chan_modem.so chan_iax.so chan_sip.so \
|
||||||
chan_modem_aopen.so \
|
chan_modem_aopen.so \
|
||||||
@@ -113,7 +113,7 @@ endif
|
|||||||
|
|
||||||
chan_iax.so: chan_iax.o
|
chan_iax.so: chan_iax.o
|
||||||
ifeq ($(USE_MYSQL_FRIENDS),1)
|
ifeq ($(USE_MYSQL_FRIENDS),1)
|
||||||
$(CC) $(SOLINK) -o $@ chan_iax.o -lmysqlclient -lz
|
$(CC) $(SOLINK) -o $@ chan_iax.o -L/usr/lib/mysql -lmysqlclient -lz
|
||||||
else
|
else
|
||||||
$(CC) $(SOLINK) -o $@ chan_iax.o
|
$(CC) $(SOLINK) -o $@ chan_iax.o
|
||||||
endif
|
endif
|
||||||
@@ -124,6 +124,13 @@ chan_zap.o: chan_zap.c
|
|||||||
chan_zap.so: chan_zap.o
|
chan_zap.so: chan_zap.o
|
||||||
$(CC) $(SOLINK) -o $@ $< $(ZAPPRI) $(ZAPR2) -ltonezone
|
$(CC) $(SOLINK) -o $@ $< $(ZAPPRI) $(ZAPR2) -ltonezone
|
||||||
|
|
||||||
|
chan_sip.so: chan_sip.o
|
||||||
|
ifeq ($(USE_MYSQL_FRIENDS),1)
|
||||||
|
$(CC) $(SOLINK) -o $@ chan_sip.o -L/usr/lib/mysql -lmysqlclient -lz
|
||||||
|
else
|
||||||
|
$(CC) $(SOLINK) -o $@ chan_sip.o
|
||||||
|
endif
|
||||||
|
|
||||||
chan_alsa.o: $(ALSA_SRC)
|
chan_alsa.o: $(ALSA_SRC)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,10 @@
|
|||||||
#include <netinet/in_systm.h>
|
#include <netinet/in_systm.h>
|
||||||
#include <netinet/ip.h>
|
#include <netinet/ip.h>
|
||||||
|
|
||||||
|
#ifdef MYSQL_FRIENDS
|
||||||
|
#include <mysql/mysql.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef IPTOS_MINCOST
|
#ifndef IPTOS_MINCOST
|
||||||
#define IPTOS_MINCOST 0x02
|
#define IPTOS_MINCOST 0x02
|
||||||
#endif
|
#endif
|
||||||
@@ -79,6 +83,15 @@ static int default_expiry = DEFAULT_DEFAULT_EXPIRY;
|
|||||||
#define DEFAULT_RETRANS 1000 /* How frequently to retransmit */
|
#define DEFAULT_RETRANS 1000 /* How frequently to retransmit */
|
||||||
#define MAX_RETRANS 5 /* Try only 5 times for retransmissions */
|
#define MAX_RETRANS 5 /* Try only 5 times for retransmissions */
|
||||||
|
|
||||||
|
#ifdef MYSQL_FRIENDS
|
||||||
|
static ast_mutex_t mysqllock = AST_MUTEX_INITIALIZER;
|
||||||
|
static MYSQL *mysql;
|
||||||
|
static char mydbuser[80];
|
||||||
|
static char mydbpass[80];
|
||||||
|
static char mydbhost[80];
|
||||||
|
static char mydbname[80];
|
||||||
|
#endif
|
||||||
|
|
||||||
static char *desc = "Session Initiation Protocol (SIP)";
|
static char *desc = "Session Initiation Protocol (SIP)";
|
||||||
static char *type = "SIP";
|
static char *type = "SIP";
|
||||||
static char *tdesc = "Session Initiation Protocol (SIP)";
|
static char *tdesc = "Session Initiation Protocol (SIP)";
|
||||||
@@ -341,6 +354,7 @@ struct sip_peer {
|
|||||||
int delme;
|
int delme;
|
||||||
int selfdestruct;
|
int selfdestruct;
|
||||||
int lastmsg;
|
int lastmsg;
|
||||||
|
int temponly;
|
||||||
struct sip_peer *next;
|
struct sip_peer *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -661,6 +675,102 @@ static int sip_sendtext(struct ast_channel *ast, char *text)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MYSQL_FRIENDS
|
||||||
|
|
||||||
|
static void mysql_update_peer(char *peer, struct sockaddr_in *sin)
|
||||||
|
{
|
||||||
|
if (mysql && (strlen(peer) < 128)) {
|
||||||
|
char query[512];
|
||||||
|
char *name;
|
||||||
|
time_t nowtime;
|
||||||
|
name = alloca(strlen(peer) * 2 + 1);
|
||||||
|
time(&nowtime);
|
||||||
|
mysql_real_escape_string(mysql, name, peer, strlen(peer));
|
||||||
|
snprintf(query, sizeof(query), "UPDATE sipfriends SET ipaddr=\"%s\", port=\"%d\", regseconds=\"%ld\" WHERE name=\"%s\"",
|
||||||
|
inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), nowtime, name);
|
||||||
|
ast_mutex_lock(&mysqllock);
|
||||||
|
if (mysql_real_query(mysql, query, strlen(query)))
|
||||||
|
ast_log(LOG_WARNING, "Unable to update database\n");
|
||||||
|
|
||||||
|
ast_mutex_unlock(&mysqllock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct sip_peer *mysql_peer(char *peer, struct sockaddr_in *sin)
|
||||||
|
{
|
||||||
|
struct sip_peer *p;
|
||||||
|
int success = 0;
|
||||||
|
|
||||||
|
p = malloc(sizeof(struct sip_peer));
|
||||||
|
memset(p, 0, sizeof(struct sip_peer));
|
||||||
|
if (mysql && (!peer || (strlen(peer) < 128))) {
|
||||||
|
char query[512];
|
||||||
|
char *name = NULL;
|
||||||
|
int numfields, x;
|
||||||
|
int port;
|
||||||
|
time_t regseconds, nowtime;
|
||||||
|
MYSQL_RES *result;
|
||||||
|
MYSQL_FIELD *fields;
|
||||||
|
MYSQL_ROW rowval;
|
||||||
|
if (peer) {
|
||||||
|
name = alloca(strlen(peer) * 2 + 1);
|
||||||
|
mysql_real_escape_string(mysql, name, peer, strlen(peer));
|
||||||
|
}
|
||||||
|
if (sin)
|
||||||
|
snprintf(query, sizeof(query), "SELECT * FROM sipfriends WHERE ipaddr=\"%s\" AND port=\"%d\"", inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
|
||||||
|
else
|
||||||
|
snprintf(query, sizeof(query), "SELECT * FROM sipfriends WHERE name=\"%s\"", name);
|
||||||
|
ast_mutex_lock(&mysqllock);
|
||||||
|
mysql_query(mysql, query);
|
||||||
|
if ((result = mysql_store_result(mysql))) {
|
||||||
|
if ((rowval = mysql_fetch_row(result))) {
|
||||||
|
numfields = mysql_num_fields(result);
|
||||||
|
fields = mysql_fetch_fields(result);
|
||||||
|
success = 1;
|
||||||
|
for (x=0;x<numfields;x++) {
|
||||||
|
if (rowval[x]) {
|
||||||
|
if (!strcasecmp(fields[x].name, "secret")) {
|
||||||
|
strncpy(p->secret, rowval[x], sizeof(p->secret));
|
||||||
|
} else if (!strcasecmp(fields[x].name, "name")) {
|
||||||
|
strncpy(p->name, rowval[x], sizeof(p->name) - 1);
|
||||||
|
} else if (!strcasecmp(fields[x].name, "context")) {
|
||||||
|
strncpy(p->context, rowval[x], sizeof(p->context) - 1);
|
||||||
|
} else if (!strcasecmp(fields[x].name, "ipaddr")) {
|
||||||
|
inet_aton(rowval[x], &p->addr.sin_addr);
|
||||||
|
} else if (!strcasecmp(fields[x].name, "port")) {
|
||||||
|
if (sscanf(rowval[x], "%i", &port) != 1)
|
||||||
|
port = 0;
|
||||||
|
p->addr.sin_port = htons(port);
|
||||||
|
} else if (!strcasecmp(fields[x].name, "regseconds")) {
|
||||||
|
if (sscanf(rowval[x], "%li", ®seconds) != 1)
|
||||||
|
regseconds = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
time(&nowtime);
|
||||||
|
if ((nowtime - regseconds) > default_expiry)
|
||||||
|
memset(&p->addr, 0, sizeof(p->addr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ast_mutex_unlock(&mysqllock);
|
||||||
|
}
|
||||||
|
if (!success) {
|
||||||
|
free(p);
|
||||||
|
p = NULL;
|
||||||
|
} else {
|
||||||
|
p->dynamic = 1;
|
||||||
|
p->capability = capability;
|
||||||
|
p->nat = globalnat;
|
||||||
|
p->dtmfmode = globaldtmfmode;
|
||||||
|
p->insecure = 1;
|
||||||
|
p->expire = -1;
|
||||||
|
p->temponly = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
#endif /* MYSQL_FRIENDS */
|
||||||
|
|
||||||
static int create_addr(struct sip_pvt *r, char *peer)
|
static int create_addr(struct sip_pvt *r, char *peer)
|
||||||
{
|
{
|
||||||
struct hostent *hp;
|
struct hostent *hp;
|
||||||
@@ -674,7 +784,16 @@ static int create_addr(struct sip_pvt *r, char *peer)
|
|||||||
ast_mutex_lock(&peerl.lock);
|
ast_mutex_lock(&peerl.lock);
|
||||||
p = peerl.peers;
|
p = peerl.peers;
|
||||||
while(p) {
|
while(p) {
|
||||||
if (!strcasecmp(p->name, peer)) {
|
if (!strcasecmp(p->name, peer))
|
||||||
|
break;
|
||||||
|
p = p->next;
|
||||||
|
}
|
||||||
|
#ifdef MYSQL_FRIENDS
|
||||||
|
if (!p)
|
||||||
|
p = mysql_peer(peer, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (p) {
|
||||||
found++;
|
found++;
|
||||||
r->capability = p->capability;
|
r->capability = p->capability;
|
||||||
r->nat = p->nat;
|
r->nat = p->nat;
|
||||||
@@ -724,10 +843,7 @@ static int create_addr(struct sip_pvt *r, char *peer)
|
|||||||
r->sa.sin_port = p->defaddr.sin_port;
|
r->sa.sin_port = p->defaddr.sin_port;
|
||||||
}
|
}
|
||||||
memcpy(&r->recv, &r->sa, sizeof(r->recv));
|
memcpy(&r->recv, &r->sa, sizeof(r->recv));
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
p = p->next;
|
|
||||||
}
|
}
|
||||||
ast_mutex_unlock(&peerl.lock);
|
ast_mutex_unlock(&peerl.lock);
|
||||||
if (!p && !found) {
|
if (!p && !found) {
|
||||||
@@ -764,8 +880,11 @@ static int create_addr(struct sip_pvt *r, char *peer)
|
|||||||
}
|
}
|
||||||
} else if (!p)
|
} else if (!p)
|
||||||
return -1;
|
return -1;
|
||||||
else
|
else {
|
||||||
|
if (p->temponly)
|
||||||
|
free(p);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int auto_congest(void *nothing)
|
static int auto_congest(void *nothing)
|
||||||
@@ -3355,9 +3474,14 @@ static int parse_contact(struct sip_pvt *pvt, struct sip_peer *p, struct sip_req
|
|||||||
ast_sched_del(sched, p->expire);
|
ast_sched_del(sched, p->expire);
|
||||||
if ((expiry < 1) || (expiry > max_expiry))
|
if ((expiry < 1) || (expiry > max_expiry))
|
||||||
expiry = max_expiry;
|
expiry = max_expiry;
|
||||||
p->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, p);
|
if (!p->temponly)
|
||||||
|
p->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, p);
|
||||||
pvt->expiry = expiry;
|
pvt->expiry = expiry;
|
||||||
if (inaddrcmp(&p->addr, &oldsin)) {
|
if (inaddrcmp(&p->addr, &oldsin)) {
|
||||||
|
#ifdef MYSQL_FRIENDS
|
||||||
|
if (p->temponly)
|
||||||
|
mysql_update_peer(p->name, &p->addr);
|
||||||
|
#endif
|
||||||
sip_poke_peer(p);
|
sip_poke_peer(p);
|
||||||
snprintf(data, sizeof(data), "%s:%d:%d:%s", inet_ntoa(p->addr.sin_addr), ntohs(p->addr.sin_port), expiry, p->username);
|
snprintf(data, sizeof(data), "%s:%d:%d:%s", inet_ntoa(p->addr.sin_addr), ntohs(p->addr.sin_port), expiry, p->username);
|
||||||
ast_db_put("SIP/Registry", p->name, data);
|
ast_db_put("SIP/Registry", p->name, data);
|
||||||
@@ -3630,27 +3754,33 @@ static int register_verify(struct sip_pvt *p, struct sockaddr_in *sin, struct si
|
|||||||
ast_mutex_lock(&peerl.lock);
|
ast_mutex_lock(&peerl.lock);
|
||||||
peer = peerl.peers;
|
peer = peerl.peers;
|
||||||
while(peer) {
|
while(peer) {
|
||||||
if (!strcasecmp(peer->name, name) && ast_apply_ha(peer->ha,sin)) {
|
if (!strcasecmp(peer->name, name) && ast_apply_ha(peer->ha,sin))
|
||||||
|
break;
|
||||||
|
peer = peer->next;
|
||||||
|
}
|
||||||
|
ast_mutex_unlock(&peerl.lock);
|
||||||
|
#ifdef MYSQL_FRIENDS
|
||||||
|
if (!peer)
|
||||||
|
peer = mysql_peer(name, NULL);
|
||||||
|
#endif
|
||||||
|
if (peer) {
|
||||||
if (!peer->dynamic) {
|
if (!peer->dynamic) {
|
||||||
ast_log(LOG_NOTICE, "Peer '%s' isn't dynamic\n", peer->name);
|
ast_log(LOG_NOTICE, "Peer '%s' isn't dynamic\n", peer->name);
|
||||||
break;
|
} else {
|
||||||
|
p->nat = peer->nat;
|
||||||
|
transmit_response(p, "100 Trying", req);
|
||||||
|
if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, peer->secret, peer->md5secret, "REGISTER", uri, 0))) {
|
||||||
|
sip_cancel_destroy(p);
|
||||||
|
if (parse_contact(p, peer, req)) {
|
||||||
|
ast_log(LOG_WARNING, "Failed to parse contact info\n");
|
||||||
|
} else {
|
||||||
|
/* Say OK and ask subsystem to retransmit msg counter */
|
||||||
|
transmit_response_with_date(p, "200 OK", req);
|
||||||
|
peer->lastmsgssent = -1;
|
||||||
|
res = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
p->nat = peer->nat;
|
|
||||||
transmit_response(p, "100 Trying", req);
|
|
||||||
if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, peer->secret, peer->md5secret, "REGISTER", uri, 0))) {
|
|
||||||
sip_cancel_destroy(p);
|
|
||||||
if (parse_contact(p, peer, req)) {
|
|
||||||
ast_log(LOG_WARNING, "Failed to parse contact info\n");
|
|
||||||
} else {
|
|
||||||
/* Say OK and ask subsystem to retransmit msg counter */
|
|
||||||
transmit_response_with_date(p, "200 OK", req);
|
|
||||||
peer->lastmsgssent = -1;
|
|
||||||
res = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
peer = peer->next;
|
|
||||||
}
|
}
|
||||||
if (!peer && autocreatepeer) {
|
if (!peer && autocreatepeer) {
|
||||||
/* Create peer if we have autocreate mode enabled */
|
/* Create peer if we have autocreate mode enabled */
|
||||||
@@ -3670,12 +3800,13 @@ static int register_verify(struct sip_pvt *p, struct sockaddr_in *sin, struct si
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast_mutex_unlock(&peerl.lock);
|
|
||||||
if (!res) {
|
if (!res) {
|
||||||
ast_device_state_changed("SIP/%s", peer->name);
|
ast_device_state_changed("SIP/%s", peer->name);
|
||||||
}
|
}
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
transmit_response(p, "401 Unauthorized", &p->initreq);
|
transmit_response(p, "401 Unauthorized", &p->initreq);
|
||||||
|
if (peer && peer->temponly)
|
||||||
|
free(peer);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4096,6 +4227,16 @@ static int check_user(struct sip_pvt *p, struct sip_request *req, char *cmd, cha
|
|||||||
while(peer) {
|
while(peer) {
|
||||||
if (!inaddrcmp(&peer->addr, &p->recv) ||
|
if (!inaddrcmp(&peer->addr, &p->recv) ||
|
||||||
(peer->insecure && (peer->addr.sin_addr.s_addr == p->recv.sin_addr.s_addr))) {
|
(peer->insecure && (peer->addr.sin_addr.s_addr == p->recv.sin_addr.s_addr))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
peer = peer->next;
|
||||||
|
}
|
||||||
|
ast_mutex_unlock(&peerl.lock);
|
||||||
|
#ifdef MYSQL_FRIENDS
|
||||||
|
if (!peer)
|
||||||
|
peer = mysql_peer(NULL, sin);
|
||||||
|
#endif
|
||||||
|
if (peer) {
|
||||||
/* Take the peer */
|
/* Take the peer */
|
||||||
p->nat = peer->nat;
|
p->nat = peer->nat;
|
||||||
if (p->rtp) {
|
if (p->rtp) {
|
||||||
@@ -4125,11 +4266,9 @@ static int check_user(struct sip_pvt *p, struct sip_request *req, char *cmd, cha
|
|||||||
else
|
else
|
||||||
p->noncodeccapability &= ~AST_RTP_DTMF;
|
p->noncodeccapability &= ~AST_RTP_DTMF;
|
||||||
}
|
}
|
||||||
break;
|
if (peer->temponly)
|
||||||
}
|
free(peer);
|
||||||
peer = peer->next;
|
|
||||||
}
|
}
|
||||||
ast_mutex_unlock(&peerl.lock);
|
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -6272,6 +6411,16 @@ static int reload_config(void)
|
|||||||
} else {
|
} else {
|
||||||
ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config);
|
ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config);
|
||||||
}
|
}
|
||||||
|
#ifdef MYSQL_FRIENDS
|
||||||
|
} else if (!strcasecmp(v->name, "dbuser")) {
|
||||||
|
strncpy(mydbuser, v->value, sizeof(mydbuser) - 1);
|
||||||
|
} else if (!strcasecmp(v->name, "dbpass")) {
|
||||||
|
strncpy(mydbpass, v->value, sizeof(mydbpass) - 1);
|
||||||
|
} else if (!strcasecmp(v->name, "dbhost")) {
|
||||||
|
strncpy(mydbhost, v->value, sizeof(mydbhost) - 1);
|
||||||
|
} else if (!strcasecmp(v->name, "dbname")) {
|
||||||
|
strncpy(mydbname, v->value, sizeof(mydbname) - 1);
|
||||||
|
#endif
|
||||||
} //else if (strcasecmp(v->name,"type"))
|
} //else if (strcasecmp(v->name,"type"))
|
||||||
// ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
|
// ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
|
||||||
v = v->next;
|
v = v->next;
|
||||||
@@ -6357,6 +6506,21 @@ static int reload_config(void)
|
|||||||
ast_mutex_unlock(&netlock);
|
ast_mutex_unlock(&netlock);
|
||||||
|
|
||||||
ast_destroy(cfg);
|
ast_destroy(cfg);
|
||||||
|
#ifdef MYSQL_FRIENDS
|
||||||
|
/* Connect to db if appropriate */
|
||||||
|
if (!mysql && strlen(mydbname)) {
|
||||||
|
mysql = mysql_init(NULL);
|
||||||
|
if (!mysql_real_connect(mysql, mydbhost[0] ? mydbhost : NULL, mydbuser, mydbpass, mydbname, 0, NULL, 0)) {
|
||||||
|
memset(mydbpass, '*', strlen(mydbpass));
|
||||||
|
ast_log(LOG_WARNING, "Database connection failed (db=%s, host=%s, user=%s, pass=%s)!\n",
|
||||||
|
mydbname, mydbhost, mydbuser, mydbpass);
|
||||||
|
free(mysql);
|
||||||
|
mysql = NULL;
|
||||||
|
} else
|
||||||
|
ast_verbose(VERBOSE_PREFIX_1 "Connected to database '%s' on '%s' as '%s'\n",
|
||||||
|
mydbname, mydbhost, mydbuser);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user