Index: chan_sip.c =================================================================== RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v retrieving revision 1.334 diff -u -r1.334 chan_sip.c --- chan_sip.c 7 Apr 2004 15:09:58 -0000 1.334 +++ chan_sip.c 8 Apr 2004 17:14:36 -0000 @@ -39,6 +39,8 @@ #include #include #include +#include +#include #include #include #include @@ -54,11 +56,6 @@ #include #include -#ifdef SIP_MYSQL_FRIENDS -#define MYSQL_FRIENDS -#include -#endif - #define VIDEO_CODEC_MASK 0x1fc0000 // Video codecs from H.261 thru AST_FORMAT_MAX_VIDEO #ifndef IPTOS_MINCOST #define IPTOS_MINCOST 0x02 @@ -73,10 +70,6 @@ #define CALLERID_UNKNOWN "Unknown" -#define SIP_DTMF_RFC2833 (1 << 0) -#define SIP_DTMF_INBAND (1 << 1) -#define SIP_DTMF_INFO (1 << 2) - static int max_expiry = DEFAULT_MAX_EXPIRY; static int default_expiry = DEFAULT_DEFAULT_EXPIRY; @@ -87,14 +80,10 @@ #define DEFAULT_RETRANS 1000 /* How frequently to retransmit */ #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 +// From acl.c... these should be moved to acl.h from here, and +// from acl.c, and then replaced with the appropriate #include (rgagnon) +#define AST_SENSE_DENY 0 +#define AST_SENSE_ALLOW 1 static char *desc = "Session Initiation Protocol (SIP)"; static char *type = "SIP"; @@ -298,76 +287,6 @@ char data[0]; }; -struct sip_user { - /* Users who can access various contexts */ - char name[80]; - char secret[80]; - char md5secret[80]; - char context[80]; - char callerid[80]; - char methods[80]; - char accountcode[20]; - char language[MAX_LANGUAGE]; - unsigned int callgroup; - unsigned int pickupgroup; - int nat; - int hascallerid; - int amaflags; - int insecure; - int canreinvite; - int capability; - int dtmfmode; - int inUse; - int incominglimit; - int outUse; - int outgoinglimit; - int restrictcid; - struct ast_ha *ha; - struct sip_user *next; -}; - -struct sip_peer { - char name[80]; - char secret[80]; - char md5secret[80]; - char context[80]; /* JK02: peers need context too to allow parking etc */ - char methods[80]; - char username[80]; - char tohost[80]; - char fromuser[80]; - char fromdomain[80]; - char mailbox[AST_MAX_EXTENSION]; - int lastmsgssent; - time_t lastmsgcheck; - int dynamic; - int expire; - int expiry; - int capability; - int insecure; - int nat; - int canreinvite; - unsigned int callgroup; - unsigned int pickupgroup; - int dtmfmode; - struct sockaddr_in addr; - struct in_addr mask; - - /* Qualification */ - struct sip_pvt *call; /* Call pointer */ - int pokeexpire; /* When to expire poke */ - int lastms; /* How long last response took (in ms), or -1 for no response */ - int maxms; /* Max ms we will accept for the host to be up, 0 to not monitor */ - struct timeval ps; /* Ping send time */ - - struct sockaddr_in defaddr; - struct ast_ha *ha; - int delme; - int selfdestruct; - int lastmsg; - int temponly; - struct sip_peer *next; -}; - static ast_mutex_t sip_reload_lock = AST_MUTEX_INITIALIZER; static int sip_reloading = 0; @@ -417,9 +336,6 @@ } regl = { NULL, AST_MUTEX_INITIALIZER }; -#define REINVITE_INVITE 1 -#define REINVITE_UPDATE 2 - static int __sip_do_register(struct sip_registry *r); static int sipsock = -1; @@ -702,109 +618,6 @@ return 0; } -#ifdef MYSQL_FRIENDS - -static void mysql_update_peer(char *peer, struct sockaddr_in *sin, char *username, int expiry) -{ - if (mysql && (strlen(peer) < 128)) { - char query[512]; - char *name; - char *uname; - time_t nowtime; - name = alloca(strlen(peer) * 2 + 1); - uname = alloca(strlen(username) * 2 + 1); - time(&nowtime); - mysql_real_escape_string(mysql, name, peer, strlen(peer)); - mysql_real_escape_string(mysql, uname, username, strlen(username)); - snprintf(query, sizeof(query), "UPDATE sipfriends SET ipaddr=\"%s\", port=\"%d\", regseconds=\"%ld\", username=\"%s\" WHERE name=\"%s\"", - inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), nowtime + expiry, uname, 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;xsecret, 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, "username")) { - strncpy(p->username, rowval[x], sizeof(p->username) - 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) - memset(&p->addr, 0, sizeof(p->addr)); - } - mysql_free_result(result); - result = NULL; - } - 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) { struct hostent *hp; @@ -822,10 +635,17 @@ break; p = p->next; } -#ifdef MYSQL_FRIENDS - if (!p) - p = mysql_peer(peer, NULL); -#endif + // Try finding peer in Query Interface + if (!p) { + // p is allocated inside of qint_sip_find_peer if needed + if (qint_sip_find_peer(&p, peer, NULL) == QINT_ERROR) { + if (p) { + ast_free_ha(p->ha); + free(p); + } + p = NULL; + } + } if (p) { found++; @@ -878,8 +698,10 @@ } memcpy(&r->recv, &r->sa, sizeof(r->recv)); } else { - if (p->temponly) + if (p->temponly) { + ast_free_ha(p->ha); free(p); + } p = NULL; } } @@ -919,8 +741,11 @@ } else if (!p) return -1; else { - if (p->temponly) + if (p->temponly) { + ast_free_ha(p->ha); free(p); + p = NULL; + } return 0; } } @@ -2955,10 +2780,8 @@ l = callerid; } /* if user want's his callerid restricted */ - if (p->restrictcid) { + if (p->restrictcid) l = CALLERID_UNKNOWN; - n = l; - } if (!n || !strlen(n)) n = l; /* Allow user to be overridden */ @@ -3842,10 +3665,27 @@ peer = peer->next; } ast_mutex_unlock(&peerl.lock); -#ifdef MYSQL_FRIENDS - if (!peer) - peer = mysql_peer(name, NULL); -#endif + + // if not found in memory, check the Query Interface + if (!peer) { + if (qint_sip_find_peer(&peer, name, NULL) == QINT_ERROR) { + if (peer) { + ast_free_ha(peer->ha); + free(peer); + } + peer = NULL; + } + + if (peer) { + // check if ACL allows this peer + if (ast_apply_ha(peer->ha, sin) == AST_SENSE_DENY) { + ast_free_ha(peer->ha); + free(peer); + peer = NULL; + } + } + } + if (peer) { if (!peer->dynamic) { ast_log(LOG_NOTICE, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); @@ -3857,10 +3697,11 @@ if (parse_contact(p, peer, req)) { ast_log(LOG_WARNING, "Failed to parse contact info\n"); } else { -#ifdef MYSQL_FRIENDS + + // if peer came from query interface, send update to it if (peer->temponly) - mysql_update_peer(peer->name, &peer->addr, peer->username, p->expiry); -#endif + qint_sip_update_peer(peer->name, &peer->addr, peer->username, p->expiry); + /* Say OK and ask subsystem to retransmit msg counter */ transmit_response_with_date(p, "200 OK", req); peer->lastmsgssent = -1; @@ -3892,8 +3733,10 @@ } if (res < 0) transmit_response(p, "401 Unauthorized", &p->initreq); - if (peer && peer->temponly) + if (peer && peer->temponly) { + ast_free_ha(peer->ha); free(peer); + } return res; } @@ -4273,46 +4116,70 @@ user = userl.users; while(user) { if (!strcasecmp(user->name, of) && ast_apply_ha(user->ha,sin)) { - p->nat = user->nat; - if (p->rtp) { - ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", p->nat); - ast_rtp_setnat(p->rtp, p->nat); - } - if (p->vrtp) { - ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", p->nat); - ast_rtp_setnat(p->vrtp, p->nat); - } - if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), user->name, user->secret, user->md5secret, cmd, uri, reliable, ignore))) { - sip_cancel_destroy(p); - if (strlen(user->context)) - strncpy(p->context, user->context, sizeof(p->context) - 1); - if (strlen(user->callerid) && strlen(p->callerid)) - strncpy(p->callerid, user->callerid, sizeof(p->callerid) - 1); - strncpy(p->username, user->name, sizeof(p->username) - 1); - strncpy(p->peersecret, user->secret, sizeof(p->peersecret) - 1); - strncpy(p->peermd5secret, user->md5secret, sizeof(p->peermd5secret) - 1); - strncpy(p->accountcode, user->accountcode, sizeof(p->accountcode) -1); - strncpy(p->language, user->language, sizeof(p->language) -1); - p->canreinvite = user->canreinvite; - p->amaflags = user->amaflags; - p->callgroup = user->callgroup; - p->pickupgroup = user->pickupgroup; - p->restrictcid = user->restrictcid; - p->capability = user->capability; - p->jointcapability = user->capability; - if (user->dtmfmode) { - p->dtmfmode = user->dtmfmode; - if (p->dtmfmode & SIP_DTMF_RFC2833) - p->noncodeccapability |= AST_RTP_DTMF; - else - p->noncodeccapability &= ~AST_RTP_DTMF; - } - } break; } user = user->next; } + + //if not found in memory, try the Query Interface + if (!user) { + if (qint_sip_find_user(&user, of) == QINT_ERROR) { + if (user) { + ast_free_ha(user->ha); + free(user); + } + user = NULL; + } + + if (user) { + //check if user is denied in ACL + if (ast_apply_ha(user->ha, sin) == AST_SENSE_DENY) { + ast_free_ha(user->ha); + free(user); + user = NULL; + } + } + } + + if (user) { + p->nat = user->nat; + if (p->rtp) { + ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", p->nat); + ast_rtp_setnat(p->rtp, p->nat); + } + if (p->vrtp) { + ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", p->nat); + ast_rtp_setnat(p->vrtp, p->nat); + } + if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), user->name, user->secret, user->md5secret, cmd, uri, reliable, ignore))) { + sip_cancel_destroy(p); + if (strlen(user->context)) + strncpy(p->context, user->context, sizeof(p->context) - 1); + if (strlen(user->callerid) && strlen(p->callerid)) + strncpy(p->callerid, user->callerid, sizeof(p->callerid) - 1); + strncpy(p->username, user->name, sizeof(p->username) - 1); + strncpy(p->peersecret, user->secret, sizeof(p->peersecret) - 1); + strncpy(p->peermd5secret, user->md5secret, sizeof(p->peermd5secret) - 1); + strncpy(p->accountcode, user->accountcode, sizeof(p->accountcode) -1); + strncpy(p->language, user->language, sizeof(p->language) -1); + p->canreinvite = user->canreinvite; + p->amaflags = user->amaflags; + p->callgroup = user->callgroup; + p->pickupgroup = user->pickupgroup; + p->restrictcid = user->restrictcid; + p->capability = user->capability; + p->jointcapability = user->capability; + if (user->dtmfmode) { + p->dtmfmode = user->dtmfmode; + if (p->dtmfmode & SIP_DTMF_RFC2833) + p->noncodeccapability |= AST_RTP_DTMF; + else + p->noncodeccapability &= ~AST_RTP_DTMF; + } + } + } ast_mutex_unlock(&userl.lock); + if (!user) { /* If we didn't find a user match, check for peers */ ast_mutex_lock(&peerl.lock); @@ -4325,44 +4192,60 @@ peer = peer->next; } ast_mutex_unlock(&peerl.lock); -#ifdef MYSQL_FRIENDS - if (!peer) - peer = mysql_peer(NULL, sin); -#endif - if (peer) { - /* Take the peer */ - p->nat = peer->nat; - if (p->rtp) { - ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", p->nat); - ast_rtp_setnat(p->rtp, p->nat); - } - if (p->vrtp) { - ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", p->nat); - ast_rtp_setnat(p->vrtp, p->nat); - } - p->canreinvite = peer->canreinvite; - if (strlen(peer->username)) - strncpy(p->username, peer->username, sizeof(p->username) - 1); - strncpy(p->peername, peer->name, sizeof(p->peername) - 1); - if (strlen(peer->context)) - strncpy(p->context, peer->context, sizeof(p->context) - 1); - strncpy(p->peersecret, peer->secret, sizeof(p->peersecret) - 1); - strncpy(p->peermd5secret, peer->md5secret, sizeof(p->peermd5secret) - 1); - p->callgroup = peer->callgroup; - p->pickupgroup = peer->pickupgroup; - p->capability = peer->capability; - p->jointcapability = peer->capability; - if (peer->dtmfmode) { - p->dtmfmode = peer->dtmfmode; - if (p->dtmfmode & SIP_DTMF_RFC2833) - p->noncodeccapability |= AST_RTP_DTMF; - else - p->noncodeccapability &= ~AST_RTP_DTMF; + + // if not found in memory, check the query interface + if (!peer) { + if (qint_sip_find_peer(&peer, NULL, sin) == QINT_ERROR) { + if (peer) { + ast_free_ha(peer->ha); + free(peer); } - if (peer->temponly) + peer = NULL; + } + } + + if (peer) { + /* Take the peer */ + p->nat = peer->nat; + if (p->rtp) { + ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", p->nat); + ast_rtp_setnat(p->rtp, p->nat); + } + if (p->vrtp) { + ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", p->nat); + ast_rtp_setnat(p->vrtp, p->nat); + } + p->canreinvite = peer->canreinvite; + if (strlen(peer->username)) + strncpy(p->username, peer->username, sizeof(p->username) - 1); + strncpy(p->peername, peer->name, sizeof(p->peername) - 1); + if (strlen(peer->context)) + strncpy(p->context, peer->context, sizeof(p->context) - 1); + strncpy(p->peersecret, peer->secret, sizeof(p->peersecret) - 1); + strncpy(p->peermd5secret, peer->md5secret, sizeof(p->peermd5secret) - 1); + p->callgroup = peer->callgroup; + p->pickupgroup = peer->pickupgroup; + p->capability = peer->capability; + p->jointcapability = peer->capability; + if (peer->dtmfmode) { + p->dtmfmode = peer->dtmfmode; + if (p->dtmfmode & SIP_DTMF_RFC2833) + p->noncodeccapability |= AST_RTP_DTMF; + else + p->noncodeccapability &= ~AST_RTP_DTMF; + } + if (peer->temponly) { + ast_free_ha(peer->ha); free(peer); + peer = NULL; + } } } + if (user && user->temponly) { + ast_free_ha(user->ha); + free(user); + user = NULL; + } return res; } @@ -6577,16 +6460,6 @@ } else { 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")) // ast_log(LOG_WARNING, "Ignoring %s\n", v->name); v = v->next; @@ -6672,21 +6545,6 @@ ast_mutex_unlock(&netlock); 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; }