~davewalker/ubuntu/maverick/asterisk/lp_705014

« back to all changes in this revision

Viewing changes to channels/chan_iax.c

  • Committer: Bazaar Package Importer
  • Author(s): Kilian Krause
  • Date: 2005-03-09 22:09:05 UTC
  • mto: (1.2.1 upstream) (8.2.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20050309220905-9afy6hcpw96xbr6j
Tags: upstream-1.0.6
ImportĀ upstreamĀ versionĀ 1.0.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
#include <asterisk/crypto.h>
30
30
#include <asterisk/acl.h>
31
31
#include <asterisk/manager.h>
 
32
#include <asterisk/utils.h>
32
33
#include <arpa/inet.h>
33
34
#include <sys/socket.h>
34
35
#include <netinet/in.h>
42
43
#include <unistd.h>
43
44
#include <netdb.h>
44
45
#include <fcntl.h>
45
 
#include <pthread.h>
46
46
#include <signal.h>
47
47
#include <sys/signal.h>
48
48
 
79
79
#define GAMMA (0.01)
80
80
 
81
81
#ifdef MYSQL_FRIENDS
82
 
static ast_mutex_t mysqllock = AST_MUTEX_INITIALIZER;
 
82
AST_MUTEX_DEFINE_STATIC(mysqllock);
83
83
static MYSQL *mysql;
84
84
static char mydbuser[80];
85
85
static char mydbpass[80];
111
111
static int expirey = AST_DEFAULT_REG_EXPIRE;
112
112
 
113
113
static int usecnt;
114
 
static ast_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER;
 
114
AST_MUTEX_DEFINE_STATIC(usecnt_lock);
115
115
 
116
116
int (*iax_regfunk)(char *username, int onoff) = NULL;
117
117
 
446
446
        struct iax_dpcache *peer;       /* For linking in peers */
447
447
} *dpcache;
448
448
 
449
 
static ast_mutex_t dpcache_lock;
 
449
AST_MUTEX_DEFINE_STATIC(dpcache_lock);
450
450
 
451
451
#ifdef DEBUG_SUPPORT
452
452
static void showframe(struct ast_iax_frame *f, struct ast_iax_full_hdr *fhi, int rx, struct sockaddr_in *sin)
504
504
                "TKOFFHK ",
505
505
                "OFFHOOK" };
506
506
        struct ast_iax_full_hdr *fh;
507
 
        char retries[20];
 
507
        char retries[20] = "";
508
508
        char class2[20];
509
509
        char subclass2[20];
510
510
        char *class;
511
511
        char *subclass;
 
512
        char iabuf[INET_ADDRSTRLEN];
512
513
        if (f) {
513
514
                fh = f->data;
514
515
                snprintf(retries, sizeof(retries), "%03d", f->retries);
515
516
        } else {
516
 
                strcpy(retries, "N/A");
 
517
                strncpy(retries, "N/A", sizeof(retries) - 1);
517
518
                fh = fhi;
518
519
        }
519
520
        if (!(ntohs(fh->callno) & AST_FLAG_FULL)) {
527
528
                class = frames[(int)fh->type];
528
529
        }
529
530
        if (fh->type == AST_FRAME_DTMF) {
530
 
                sprintf(subclass2, "%c", fh->csub);
 
531
                snprintf(subclass2, sizeof(subclass2), "%c", fh->csub);
531
532
                subclass = subclass2;
532
533
        } else if (fh->type == AST_FRAME_IAX) {
533
534
                if (fh->csub >= sizeof(iaxs)/sizeof(iaxs[0])) {
555
556
"   Timestamp: %05ldms  Callno: %5.5d  DCall: %5.5d [%s:%d]\n",
556
557
        (long)ntohl(fh->ts),
557
558
        (short)(ntohs(fh->callno) & ~AST_FLAG_FULL), (short) ntohs(fh->dcallno),
558
 
                inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
 
559
                ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port));
559
560
}
560
561
#endif
561
562
 
682
683
                samples = f->datalen;
683
684
                break;
684
685
        case AST_FORMAT_ADPCM:
 
686
        case AST_FORMAT_G726:
685
687
                samples = f->datalen *2;
686
688
                break;
687
689
        case AST_FORMAT_SPEEX:
818
820
                        iaxs[x]->callno = x;
819
821
                        iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
820
822
                        iaxs[x]->expirey = expirey;
821
 
                        iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)x);
822
 
                        iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)x);
 
823
                        iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
 
824
                        iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
823
825
                        iaxs[x]->amaflags = amaflags;
824
826
                        strncpy(iaxs[x]->accountcode, accountcode, sizeof(iaxs[x]->accountcode)-1);
825
827
                } else {
838
840
        /* Assumes lock for callno is already held... */
839
841
        for (;;) {
840
842
                pass++;
841
 
                if (!ast_mutex_trylock(&iaxsl[callno])) {
842
 
                        ast_log(LOG_WARNING, "Lock is not held on pass %d of iax_queue_frame\n", pass);
843
 
                        CRASH;
844
 
                }
845
843
                if (iaxs[callno] && iaxs[callno]->owner) {
846
844
                        if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
847
845
                                /* Avoid deadlock by pausing and trying again */
849
847
                                usleep(1);
850
848
                                ast_mutex_lock(&iaxsl[callno]);
851
849
                        } else {
852
 
                                ast_queue_frame(iaxs[callno]->owner, f, 0);
 
850
                                ast_queue_frame(iaxs[callno]->owner, f);
853
851
                                ast_mutex_unlock(&iaxs[callno]->owner->lock);
854
852
                                break;
855
853
                        }
928
926
                if (m.msg_controllen) {
929
927
                        sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
930
928
                        if (sin) 
931
 
                                ast_log(LOG_WARNING, "Receive error from %s\n", inet_ntoa(sin->sin_addr));
 
929
                                ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
932
930
                        else
933
931
                                ast_log(LOG_WARNING, "No address detected??\n");
934
932
                } else {
942
940
static int send_packet(struct ast_iax_frame *f)
943
941
{
944
942
        int res;
 
943
        char iabuf[INET_ADDRSTRLEN];
945
944
        /* Called with iaxsl held */
946
945
        if (option_debug)
947
 
                ast_log(LOG_DEBUG, "Sending %d on %d/%d to %s:%d\n", f->ts, f->callno, iaxs[f->callno]->peercallno, inet_ntoa(iaxs[f->callno]->addr.sin_addr), ntohs(iaxs[f->callno]->addr.sin_port));
 
946
                ast_log(LOG_DEBUG, "Sending %d on %d/%d to %s:%d\n", f->ts, f->callno, iaxs[f->callno]->peercallno, ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[f->callno]->addr.sin_addr), ntohs(iaxs[f->callno]->addr.sin_port));
948
947
        /* Don't send if there was an error, but return error instead */
949
948
        if (f->callno < 0) {
950
949
                ast_log(LOG_WARNING, "Call number = %d\n", f->callno);
1076
1075
                        /* If there's an owner, prod it to give up */
1077
1076
                        owner->pvt->pvt = NULL;
1078
1077
                        owner->_softhangup |= AST_SOFTHANGUP_DEV;
1079
 
                        ast_queue_hangup(owner, 0);
 
1078
                        ast_queue_hangup(owner);
1080
1079
                }
1081
1080
 
1082
1081
                for (cur = iaxq.head; cur ; cur = cur->next) {
1111
1110
        struct ast_iax_frame *f = data;
1112
1111
        int freeme=0;
1113
1112
        int callno = f->callno;
 
1113
        char iabuf[INET_ADDRSTRLEN];
1114
1114
        /* Make sure this call is still active */
1115
1115
        if (callno > -1) 
1116
1116
                ast_mutex_lock(&iaxsl[callno]);
1127
1127
                                                        iax_destroy_nolock(f->callno);
1128
1128
                                        } else {
1129
1129
                                                if (iaxs[f->callno]->owner)
1130
 
                                                        ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, ts=%d, seqno=%d)\n", inet_ntoa(iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->f->frametype, f->f->subclass, f->ts, f->seqno);
 
1130
                                                        ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, ts=%d, seqno=%d)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->f->frametype, f->f->subclass, f->ts, f->seqno);
1131
1131
                                                iaxs[f->callno]->error = ETIMEDOUT;
1132
1132
                                                if (iaxs[f->callno]->owner) {
1133
1133
                                                        struct ast_frame fr = { 0, };
1243
1243
static int iax_show_cache(int fd, int argc, char *argv[])
1244
1244
{
1245
1245
        struct iax_dpcache *dp;
1246
 
        char tmp[1024], *pc;
 
1246
        char tmp[1024] = "", *pc;
1247
1247
        int s;
1248
1248
        int x,y;
1249
1249
        struct timeval tv;
1253
1253
        ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
1254
1254
        while(dp) {
1255
1255
                s = dp->expirey.tv_sec - tv.tv_sec;
1256
 
                strcpy(tmp, "");
 
1256
                tmp[0] = '\0';
1257
1257
                if (dp->flags & CACHE_FLAG_EXISTS)
1258
 
                        strcat(tmp, "EXISTS|");
 
1258
                        strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
1259
1259
                if (dp->flags & CACHE_FLAG_NONEXISTANT)
1260
 
                        strcat(tmp, "NONEXISTANT|");
 
1260
                        strncat(tmp, "NONEXISTANT|", sizeof(tmp) - strlen(tmp) - 1);
1261
1261
                if (dp->flags & CACHE_FLAG_CANEXIST)
1262
 
                        strcat(tmp, "CANEXIST|");
 
1262
                        strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
1263
1263
                if (dp->flags & CACHE_FLAG_PENDING)
1264
 
                        strcat(tmp, "PENDING|");
 
1264
                        strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
1265
1265
                if (dp->flags & CACHE_FLAG_TIMEOUT)
1266
 
                        strcat(tmp, "TIMEOUT|");
 
1266
                        strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
1267
1267
                if (dp->flags & CACHE_FLAG_TRANSMITTED)
1268
 
                        strcat(tmp, "TRANSMITTED|");
 
1268
                        strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
1269
1269
                if (dp->flags & CACHE_FLAG_MATCHMORE)
1270
 
                        strcat(tmp, "MATCHMORE|");
 
1270
                        strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
1271
1271
                if (dp->flags & CACHE_FLAG_UNKNOWN)
1272
 
                        strcat(tmp, "UNKNOWN|");
 
1272
                        strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
1273
1273
                /* Trim trailing pipe */
1274
1274
                if (strlen(tmp))
1275
1275
                        tmp[strlen(tmp) - 1] = '\0';
1276
1276
                else
1277
 
                        strcpy(tmp, "(none)");
 
1277
                        strncpy(tmp, "(none)", sizeof(tmp) - 1);
1278
1278
                y=0;
1279
1279
                pc = strchr(dp->peercontext, '@');
1280
1280
                if (!pc)
1534
1534
                time(&nowtime);
1535
1535
                mysql_real_escape_string(mysql, name, peer, strlen(peer));
1536
1536
                snprintf(query, sizeof(query), "UPDATE iax1friends SET ipaddr=\"%s\", port=\"%d\", regseconds=\"%ld\" WHERE name=\"%s\"", 
1537
 
                        inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), nowtime, name);
 
1537
                        ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port), nowtime, name);
1538
1538
                ast_mutex_lock(&mysqllock);
1539
1539
                if (mysql_real_query(mysql, query, strlen(query))) 
1540
1540
                        ast_log(LOG_WARNING, "Unable to update database\n");
1561
1561
                MYSQL_ROW rowval;
1562
1562
                name = alloca(strlen(peer) * 2 + 1);
1563
1563
                mysql_real_escape_string(mysql, name, peer, strlen(peer));
1564
 
                snprintf(query, sizeof(query), "SELECT * FROM iax1friends WHERE name=\"%s\"", name);
 
1564
                snprintf(query, sizeof(query), "SELECT name, secret, context, ipaddr, port, regseconds FROM iax1friends WHERE name=\"%s\"", name);
1565
1565
                ast_mutex_lock(&mysqllock);
1566
1566
                mysql_query(mysql, query);
1567
1567
                if ((result = mysql_store_result(mysql))) {
1572
1572
                                for (x=0;x<numfields;x++) {
1573
1573
                                        if (rowval[x]) {
1574
1574
                                                if (!strcasecmp(fields[x].name, "secret")) {
1575
 
                                                        strncpy(p->secret, rowval[x], sizeof(p->secret));
 
1575
                                                        strncpy(p->secret, rowval[x], sizeof(p->secret) - 1);
1576
1576
                                                } else if (!strcasecmp(fields[x].name, "context")) {
1577
1577
                                                        strncpy(p->context, rowval[x], sizeof(p->context) - 1);
1578
1578
                                                } else if (!strcasecmp(fields[x].name, "ipaddr")) {
1603
1603
                p->delme = 1;
1604
1604
                p->expire = -1;
1605
1605
                p->capability = iax_capability;
1606
 
                strcpy(p->methods, "md5,plaintext");
 
1606
                strncpy(p->methods, "md5,plaintext", sizeof(p->methods) - 1);
1607
1607
        }
1608
1608
        return p;
1609
1609
}
1618
1618
        memset(p, 0, sizeof(struct iax_user));
1619
1619
        con = malloc(sizeof(struct iax_context));
1620
1620
        memset(con, 0, sizeof(struct iax_context));
1621
 
        strcpy(con->context, "default");
 
1621
        strncpy(con->context, "default", sizeof(con->context) - 1);
1622
1622
        p->contexts = con;
1623
1623
        if (mysql && (strlen(user) < 128)) {
1624
1624
                char query[512];
1629
1629
                MYSQL_ROW rowval;
1630
1630
                name = alloca(strlen(user) * 2 + 1);
1631
1631
                mysql_real_escape_string(mysql, name, user, strlen(user));
1632
 
                snprintf(query, sizeof(query), "SELECT * FROM iax1friends WHERE name=\"%s\"", name);
 
1632
                snprintf(query, sizeof(query), "SELECT name, secret, context, ipaddr, port, regseconds FROM iax1friends WHERE name=\"%s\"", name);
1633
1633
                ast_mutex_lock(&mysqllock);
1634
1634
                mysql_query(mysql, query);
1635
1635
                if ((result = mysql_store_result(mysql))) {
1640
1640
                                for (x=0;x<numfields;x++) {
1641
1641
                                        if (rowval[x]) {
1642
1642
                                                if (!strcasecmp(fields[x].name, "secret")) {
1643
 
                                                        strncpy(p->secret, rowval[x], sizeof(p->secret));
 
1643
                                                        strncpy(p->secret, rowval[x], sizeof(p->secret) - 1);
1644
1644
                                                } else if (!strcasecmp(fields[x].name, "context")) {
1645
1645
                                                        strncpy(p->contexts->context, rowval[x], sizeof(p->contexts->context) - 1);
1646
1646
                                                }
1658
1658
        } else {
1659
1659
                strncpy(p->name, user, sizeof(p->name) - 1);
1660
1660
                p->delme = 1;
1661
 
                strcpy(p->methods, "md5,plaintext");
 
1661
                strncpy(p->methods, "md5,plaintext", sizeof(p->methods) - 1);
1662
1662
        }
1663
1663
        return p;
1664
1664
}
1841
1841
        if (p->maxtime) {
1842
1842
                /* Initialize pingtime and auto-congest time */
1843
1843
                p->pingtime = p->maxtime / 2;
1844
 
                p->initid = ast_sched_add(sched, p->maxtime * 2, auto_congest, (void *)p->callno);
 
1844
                p->initid = ast_sched_add(sched, p->maxtime * 2, auto_congest, (void *)(long)p->callno);
1845
1845
        }
1846
1846
        send_command(p, AST_FRAME_IAX,
1847
1847
                AST_IAX_COMMAND_NEW, 0, requeststr, strlen(requeststr) + 1, -1);
1905
1905
        int res;
1906
1906
        char req0[256];
1907
1907
        char req1[256];
 
1908
        char iabuf[INET_ADDRSTRLEN];
1908
1909
        struct chan_iax_pvt *p0 = c0->pvt->pvt;
1909
1910
        struct chan_iax_pvt *p1 = c1->pvt->pvt;
1910
 
        snprintf(req0, sizeof(req0), "remip=%s;remport=%d;remcall=%d;", inet_ntoa(p1->addr.sin_addr), ntohs(p1->addr.sin_port), p1->peercallno);
1911
 
        snprintf(req1, sizeof(req1), "remip=%s;remport=%d;remcall=%d;", inet_ntoa(p0->addr.sin_addr), ntohs(p0->addr.sin_port), p0->peercallno);
 
1911
        snprintf(req0, sizeof(req0), "remip=%s;remport=%d;remcall=%d;", ast_inet_ntoa(iabuf, sizeof(iabuf), p1->addr.sin_addr), ntohs(p1->addr.sin_port), p1->peercallno);
 
1912
        snprintf(req1, sizeof(req1), "remip=%s;remport=%d;remcall=%d;", ast_inet_ntoa(iabuf, sizeof(iabuf), p0->addr.sin_addr), ntohs(p0->addr.sin_port), p0->peercallno);
1912
1913
        res = send_command(p0, AST_FRAME_IAX, AST_IAX_COMMAND_TXREQ, 0, req0, strlen(req0) + 1, -1);
1913
1914
        if (res)
1914
1915
                return -1;
2082
2083
{
2083
2084
        char host[256];
2084
2085
        struct ast_channel *tmp;
 
2086
        char iabuf[INET_ADDRSTRLEN];
2085
2087
        tmp = ast_channel_alloc(1);
2086
2088
        if (tmp) {
2087
2089
                if (!iax_getpeername(i->addr, host, sizeof(host)))
2088
 
                        snprintf(host, sizeof(host), "%s:%d", inet_ntoa(i->addr.sin_addr), ntohs(i->addr.sin_port));
 
2090
                        snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), i->addr.sin_addr), ntohs(i->addr.sin_port));
2089
2091
                if (strlen(i->username))
2090
2092
                        snprintf(tmp->name, sizeof(tmp->name), "IAX[%s@%s]/%d", i->username, host, i->callno);
2091
2093
                else
2337
2339
#define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-8d  %-10s\n"
2338
2340
        struct iax_peer *peer;
2339
2341
        char name[256] = "";
 
2342
        char iabuf[INET_ADDRSTRLEN];
2340
2343
        if (argc != 3)
2341
2344
                return RESULT_SHOWUSAGE;
2342
2345
        ast_mutex_lock(&peerl.lock);
2343
2346
        ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "Status");
2344
2347
        for (peer = peerl.peers;peer;peer = peer->next) {
2345
2348
                char nm[20];
2346
 
                char status[20];
 
2349
                char status[20] = "";
2347
2350
                if (strlen(peer->username))
2348
2351
                        snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
2349
2352
                else
2350
2353
                        strncpy(name, peer->name, sizeof(name) - 1);
2351
2354
                if (peer->maxms) {
2352
2355
                        if (peer->lastms < 0)
2353
 
                                strcpy(status, "UNREACHABLE");
 
2356
                                strncpy(status, "UNREACHABLE", sizeof(status) - 1);
2354
2357
                        else if (peer->lastms > peer->maxms) 
2355
2358
                                snprintf(status, sizeof(status), "LAGGED (%d ms)", peer->lastms);
2356
2359
                        else if (peer->lastms) 
2357
2360
                                snprintf(status, sizeof(status), "OK (%d ms)", peer->lastms);
2358
2361
                        else 
2359
 
                                strcpy(status, "UNKNOWN");
 
2362
                                strncpy(status, "UNKNOWN", sizeof(status) - 1);
2360
2363
                } else 
2361
 
                        strcpy(status, "Unmonitored");
2362
 
                strncpy(nm, inet_ntoa(peer->mask), sizeof(nm)-1);
 
2364
                        strncpy(status, "Unmonitored", sizeof(status) - 1);
 
2365
                strncpy(nm, ast_inet_ntoa(iabuf, sizeof(iabuf), peer->mask), sizeof(nm)-1);
2363
2366
                ast_cli(fd, FORMAT, name, 
2364
 
                                        peer->addr.sin_addr.s_addr ? inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
 
2367
                                        peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)",
2365
2368
                                        peer->dynamic ? "(D)" : "(S)",
2366
2369
                                        nm,
2367
2370
                                        ntohs(peer->addr.sin_port), status);
2410
2413
#define FORMAT "%-20.20s  %-10.10s  %-20.20s %8d  %s\n"
2411
2414
        struct iax_registry *reg;
2412
2415
        char host[80];
2413
 
        char perceived[80];
 
2416
        char perceived[80] = "";
 
2417
        char iabuf[INET_ADDRSTRLEN];
2414
2418
        if (argc != 3)
2415
2419
                return RESULT_SHOWUSAGE;
2416
2420
        ast_mutex_lock(&peerl.lock);
2417
2421
        ast_cli(fd, FORMAT2, "Host", "Username", "Perceived", "Refresh", "State");
2418
2422
        for (reg = registrations;reg;reg = reg->next) {
2419
 
                snprintf(host, sizeof(host), "%s:%d", inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
 
2423
                snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->addr.sin_addr), ntohs(reg->addr.sin_port));
2420
2424
                if (reg->us.sin_addr.s_addr) 
2421
 
                        snprintf(perceived, sizeof(perceived), "%s:%d", inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
 
2425
                        snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->us.sin_addr), ntohs(reg->us.sin_port));
2422
2426
                else
2423
 
                        strcpy(perceived, "<Unregistered>");
 
2427
                        strncpy(perceived, "<Unregistered>", sizeof(perceived) - 1);
2424
2428
                ast_cli(fd, FORMAT, host, 
2425
2429
                                        reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
2426
2430
        }
2436
2440
#define FORMAT  "%-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  %-5.5dms  %-4.4dms  %-6.6s\n"
2437
2441
        int x;
2438
2442
        int numchans = 0;
 
2443
        char iabuf[INET_ADDRSTRLEN];
2439
2444
        if (argc != 3)
2440
2445
                return RESULT_SHOWUSAGE;
2441
2446
        ast_cli(fd, FORMAT2, "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "Format");
2442
2447
        for (x=0;x<AST_IAX_MAX_CALLS;x++) {
2443
2448
                ast_mutex_lock(&iaxsl[x]);
2444
2449
                if (iaxs[x]) {
2445
 
                        ast_cli(fd, FORMAT, inet_ntoa(iaxs[x]->addr.sin_addr), 
 
2450
                        ast_cli(fd, FORMAT, ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[x]->addr.sin_addr), 
2446
2451
                                                strlen(iaxs[x]->username) ? iaxs[x]->username : "(None)", 
2447
2452
                                                iaxs[x]->callno, iaxs[x]->peercallno, 
2448
2453
                                                iaxs[x]->oseqno, iaxs[x]->iseqno, 
2629
2634
        char *var, *value;
2630
2635
        struct iax_user *user;
2631
2636
        char request[256];
 
2637
        char iabuf[INET_ADDRSTRLEN];
2632
2638
        int gotcapability=0;
2633
2639
        char *stringp=NULL;
2634
2640
        strncpy(request, orequest, sizeof(request)-1);
2673
2679
                iaxs[callno]->peercapability = iaxs[callno]->peerformat;
2674
2680
        if (version > AST_IAX_PROTO_VERSION) {
2675
2681
                ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
2676
 
                        inet_ntoa(sin->sin_addr), version);
 
2682
                        ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), version);
2677
2683
                return res;
2678
2684
        }
2679
2685
        ast_mutex_lock(&userl.lock);
2718
2724
                /* Copy the secret */
2719
2725
                strncpy(iaxs[callno]->secret, user->secret, sizeof(iaxs[callno]->secret)-1);
2720
2726
                /* And any input keys */
2721
 
                strncpy(iaxs[callno]->inkeys, user->inkeys, sizeof(iaxs[callno]->inkeys));
 
2727
                strncpy(iaxs[callno]->inkeys, user->inkeys, sizeof(iaxs[callno]->inkeys) - 1);
2722
2728
                /* And the permitted authentication methods */
2723
2729
                strncpy(iaxs[callno]->methods, user->methods, sizeof(iaxs[callno]->methods)-1);
2724
2730
                /* If they have callerid, override the given caller id.  Always store the ANI */
2739
2745
static int raw_hangup(struct sockaddr_in *sin, short src, short dst)
2740
2746
{
2741
2747
        struct ast_iax_full_hdr fh;
 
2748
        char iabuf[INET_ADDRSTRLEN];
2742
2749
        fh.callno = htons(src | AST_FLAG_FULL);
2743
2750
        fh.dcallno = htons(dst);
2744
2751
        fh.ts = 0;
2749
2756
        if (option_debug)
2750
2757
#endif  
2751
2758
                ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
2752
 
                        inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
 
2759
                        ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port), src, dst);
2753
2760
        return sendto(netsocket, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
2754
2761
}
2755
2762
 
2803
2810
        if (strstr(p->methods, "rsa") && strlen(rsasecret) && strlen(p->inkeys)) {
2804
2811
                struct ast_key *key;
2805
2812
                char *keyn;
2806
 
                char tmpkey[256];
 
2813
                char tmpkey[256] = "";
2807
2814
                char *stringp=NULL;
2808
 
                strncpy(tmpkey, p->inkeys, sizeof(tmpkey));
 
2815
                strncpy(tmpkey, p->inkeys, sizeof(tmpkey) - 1);
2809
2816
                stringp=tmpkey;
2810
2817
                keyn = strsep(&stringp, ":");
2811
2818
                while(keyn) {
2844
2851
        char md5secret[256] = "";
2845
2852
        char rsasecret[256] = "";
2846
2853
        char secret[256] = "";
 
2854
        char iabuf[INET_ADDRSTRLEN];
2847
2855
        struct iax_peer *p;
2848
2856
        struct ast_key *key;
2849
2857
        char *var;
2854
2862
        char *stringp=NULL;
2855
2863
 
2856
2864
        iaxs[callno]->state &= ~IAX_STATE_AUTHENTICATED;
2857
 
        strcpy(iaxs[callno]->peer, "");
 
2865
        iaxs[callno]->peer[0] = '\0';
2858
2866
        if (!orequest)
2859
2867
                return -1;
2860
2868
        strncpy(request, orequest, sizeof(request)-1);
2882
2890
        }
2883
2891
 
2884
2892
        if (!strlen(peer)) {
2885
 
                ast_log(LOG_NOTICE, "Empty registration from %s\n", inet_ntoa(sin->sin_addr));
 
2893
                ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
2886
2894
                return -1;
2887
2895
        }
2888
2896
 
2895
2903
                p = mysql_peer(peer);
2896
2904
#endif
2897
2905
        if (!p) {
2898
 
                ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, inet_ntoa(sin->sin_addr));
 
2906
                ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
2899
2907
                return -1;
2900
2908
        }
2901
2909
 
2902
2910
        if (!p->dynamic) {
2903
 
                ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, inet_ntoa(sin->sin_addr));
 
2911
                ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
2904
2912
                if (p->delme)
2905
2913
                        free(p);
2906
2914
                return -1;
2907
2915
        }
2908
2916
 
2909
2917
        if (!ast_apply_ha(p->ha, sin)) {
2910
 
                ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", inet_ntoa(sin->sin_addr), p->name);
 
2918
                ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), p->name);
2911
2919
                if (p->delme)
2912
2920
                        free(p);
2913
2921
                return -1;
2919
2927
                if (strlen(p->inkeys)) {
2920
2928
                        char tmpkeys[256];
2921
2929
                        char *stringp=NULL;
2922
 
                        strncpy(tmpkeys, p->inkeys, sizeof(tmpkeys));
 
2930
                        strncpy(tmpkeys, p->inkeys, sizeof(tmpkeys) - 1);
2923
2931
                        stringp=tmpkeys;
2924
2932
                        keyn = strsep(&stringp, ":");
2925
2933
                        while(keyn) {
2946
2954
        } else if (strlen(secret) && strstr(p->methods, "plaintext")) {
2947
2955
                /* They've provided a plain text password and we support that */
2948
2956
                if (strcmp(secret, p->secret)) {
2949
 
                        ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", inet_ntoa(sin->sin_addr), p->name);
 
2957
                        ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), p->name);
2950
2958
                        if (p->delme)
2951
2959
                                free(p);
2952
2960
                        return -1;
2962
2970
                for (x=0;x<16;x++)
2963
2971
                        MYSNPRINTF "%2.2x", digest[x]);
2964
2972
                if (strcasecmp(requeststr, md5secret)) {
2965
 
                        ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
 
2973
                        ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), p->name, requeststr, md5secret);
2966
2974
                        if (p->delme)
2967
2975
                                free(p);
2968
2976
                        return -1;
2988
2996
{
2989
2997
        int res = -1;
2990
2998
        int x;
 
2999
        char iabuf[INET_ADDRSTRLEN];
2991
3000
        if (keyn && strlen(keyn)) {
2992
3001
                if (!strstr(methods, "rsa")) {
2993
3002
                        if (!secret || !strlen(secret)) 
2994
 
                                ast_log(LOG_NOTICE, "Asked to authenticate to %s with an RSA key, but they don't allow RSA authentication\n", inet_ntoa(sin->sin_addr));
 
3003
                                ast_log(LOG_NOTICE, "Asked to authenticate to %s with an RSA key, but they don't allow RSA authentication\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
2995
3004
                } else if (!strlen(challenge)) {
2996
 
                        ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", inet_ntoa(sin->sin_addr));
 
3005
                        ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
2997
3006
                } else {
2998
3007
                        char sig[256];
2999
3008
                        struct ast_key *key;
3030
3039
                        MYSNPRINTF2 "secret=%s;", secret);
3031
3040
                        res = 0;
3032
3041
                } else
3033
 
                        ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %s)\n", inet_ntoa(sin->sin_addr), methods);
 
3042
                        ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), methods);
3034
3043
        }
3035
3044
        return res;
3036
3045
}
3295
3304
        int ourport = 0;
3296
3305
        int refresh = 0;
3297
3306
        char ourip[256] = "<Unspecified>";
 
3307
        char iabuf[INET_ADDRSTRLEN];
3298
3308
        struct sockaddr_in oldus;
3299
3309
        char *var, *value;
3300
3310
        char *stringp=NULL;
3328
3338
        reg = iaxs[callno]->reg;
3329
3339
                        memcpy(&oldus, &reg->us, sizeof(oldus));
3330
3340
                        if (memcmp(&reg->addr, sin, sizeof(&reg->addr))) {
3331
 
                                ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", inet_ntoa(sin->sin_addr));
 
3341
                                ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
3332
3342
                                return -1;
3333
3343
                        }
3334
3344
                        if (!inet_aton(ourip, &reg->us.sin_addr)) {
3335
 
                                ast_log(LOG_WARNING, "Registry ack from '%s' contains invalid IP '%s'\n", inet_ntoa(sin->sin_addr), ourip);
 
3345
                                ast_log(LOG_WARNING, "Registry ack from '%s' contains invalid IP '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ourip);
3336
3346
                                return -1;
3337
3347
                        }
3338
3348
                        reg->us.sin_port = htons(ourport);
3344
3354
                                reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax_do_register_s, reg);
3345
3355
                        }
3346
3356
                        if (memcmp(&oldus, &reg->us, sizeof(oldus)) && (option_verbose > 2)) {
3347
 
                                snprintf(ourip, sizeof(ourip), "%s:%d", inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
3348
 
                                ast_verbose(VERBOSE_PREFIX_3 "Registered to '%s', who sees us as %s\n", inet_ntoa(sin->sin_addr), ourip);
 
3357
                                snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->us.sin_addr), ntohs(reg->us.sin_port));
 
3358
                                ast_verbose(VERBOSE_PREFIX_3 "Registered to '%s', who sees us as %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ourip);
3349
3359
                        }
3350
3360
                        reg->regstate = REG_STATE_REGISTERED;
3351
3361
                        return 0;
3432
3442
        /* Called from IAX thread only, with proper iaxsl lock */
3433
3443
        char requeststr[256] = "";
3434
3444
        struct iax_peer *p;
 
3445
        char iabuf[INET_ADDRSTRLEN];
3435
3446
        for (p = peerl.peers;p;p = p->next) {
3436
3447
                if (!strcasecmp(name, p->name)) {
3437
3448
                        break;
3451
3462
                                iax_regfunk(p->name, 1);
3452
3463
                        if  (option_verbose > 2)
3453
3464
                                ast_verbose(VERBOSE_PREFIX_3 "Registered '%s' (%s) at %s:%d\n", p->name, 
3454
 
                                        iaxs[callno]->state & IAX_STATE_AUTHENTICATED ? "AUTHENTICATED" : "UNAUTHENTICATED", inet_ntoa(sin->sin_addr), htons(sin->sin_port));
 
3465
                                        iaxs[callno]->state & IAX_STATE_AUTHENTICATED ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), htons(sin->sin_port));
3455
3466
                        iax_poke_peer(p);
3456
3467
                }               
3457
3468
                /* Update the host */
3462
3473
                if (p->expirey)
3463
3474
                        p->expire = ast_sched_add(sched, p->expirey * 1000, expire_registry, (void *)p);
3464
3475
                MYSNPRINTF "peer=%s;yourip=%s;yourport=%d;refresh=%d;",
3465
 
                        p->name, inet_ntoa(p->addr.sin_addr), ntohs(p->addr.sin_port), p->expirey);
 
3476
                        p->name, ast_inet_ntoa(iabuf, sizeof(iabuf), p->addr.sin_addr), ntohs(p->addr.sin_port), p->expirey);
3466
3477
                if (p->hascallerid)
3467
3478
                        MYSNPRINTF "callerid=%s;", p->callerid);
3468
3479
                requeststr[strlen(requeststr)-1] = '\0';
3513
3524
        char peer[256] = "";
3514
3525
        char methods[256] = "";
3515
3526
        char challenge[256] = "";
 
3527
        char iabuf[INET_ADDRSTRLEN];
3516
3528
        char *var, *value;
3517
3529
        int res;
3518
3530
        char *stringp=NULL;
3541
3553
        }
3542
3554
        reg = iaxs[callno]->reg;
3543
3555
                        if (memcmp(&reg->addr, sin, sizeof(&reg->addr))) {
3544
 
                                ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", inet_ntoa(sin->sin_addr));
 
3556
                                ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
3545
3557
                                return -1;
3546
3558
                        }
3547
3559
                        if (!strlen(reg->secret)) {
3601
3613
        /* Auto-hangup with 30 seconds of inactivity */
3602
3614
        if (iaxs[callno]->autoid > -1)
3603
3615
                ast_sched_del(sched, iaxs[callno]->autoid);
3604
 
        iaxs[callno]->autoid = ast_sched_add(sched, 30000, auto_hangup, (void *)callno);
 
3616
        iaxs[callno]->autoid = ast_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
3605
3617
        send_command(iaxs[callno], AST_FRAME_IAX, AST_IAX_COMMAND_DPREQ, 0, dp->exten, strlen(dp->exten) + 1, -1);
3606
3618
        dp->flags |= CACHE_FLAG_TRANSMITTED;
3607
3619
}
3654
3666
        int format;
3655
3667
        int exists;
3656
3668
        int mm;
3657
 
        char rel0[256];
 
3669
        char iabuf[INET_ADDRSTRLEN];
 
3670
        char rel0[256] = "";
3658
3671
        char rel1[255];
3659
3672
        char empty[32]="";              /* Safety measure */
3660
3673
        res = recvfrom(netsocket, buf, sizeof(buf), 0,(struct sockaddr *) &sin, &len);
3665
3678
                return 1;
3666
3679
        }
3667
3680
        if (res < sizeof(struct ast_iax_mini_hdr)) {
3668
 
                ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, sizeof(struct ast_iax_mini_hdr));
 
3681
                ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int)sizeof(struct ast_iax_mini_hdr));
3669
3682
                return 1;
3670
3683
        }
3671
3684
#ifdef DEBUG_SUPPORT
3764
3777
                }
3765
3778
                /* A full frame */
3766
3779
                if (res < sizeof(struct ast_iax_full_hdr)) {
3767
 
                        ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, sizeof(struct ast_iax_full_hdr));
 
3780
                        ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int)sizeof(struct ast_iax_full_hdr));
3768
3781
                        ast_mutex_unlock(&iaxsl[fr.callno]);
3769
3782
                        return 1;
3770
3783
                }
3865
3878
                                if (check_access(fr.callno, &sin, f.data, f.datalen)) {
3866
3879
                                        /* They're not allowed on */
3867
3880
                                        send_command_final(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_REJECT, 0, "No authority found", strlen("No authority found"), -1);
3868
 
                                        ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s'\n", inet_ntoa(sin.sin_addr), (char *)f.data);
 
3881
                                        ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), (char *)f.data);
3869
3882
                                        break;
3870
3883
                                }
3871
3884
                                /* This might re-enter the IAX code and need the lock */
3873
3886
                                if (!strlen(iaxs[fr.callno]->secret) && !strlen(iaxs[fr.callno]->inkeys)) {
3874
3887
                                        if (strcmp(iaxs[fr.callno]->exten, "TBD") && !exists) {
3875
3888
                                                send_command_final(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_REJECT, 0, "No such context/extension", strlen("No such context/extension"), -1);
3876
 
                                                ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", inet_ntoa(sin.sin_addr), iaxs[fr.callno]->exten, iaxs[fr.callno]->context);
 
3889
                                                ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->exten, iaxs[fr.callno]->context);
3877
3890
                                        } else {
3878
3891
                                                /* Select an appropriate format */
3879
3892
                                                format = iaxs[fr.callno]->peerformat & iax_capability;
3881
3894
                                                        format = iaxs[fr.callno]->peercapability & iax_capability;
3882
3895
                                                        if (!format) {
3883
3896
                                                                send_command_final(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_REJECT, 0, "Unable to negotiate codec", strlen("Unable to negotiate codec"), -1);
3884
 
                                                                ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible  with our capability 0x%x.\n", inet_ntoa(sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iax_capability);
 
3897
                                                                ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible  with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iax_capability);
3885
3898
                                                        } else {
3886
3899
                                                                /* Pick one... */
3887
3900
                                                                format = ast_best_codec(iaxs[fr.callno]->peercapability & iax_capability);
3888
3901
                                                                if (!format) {
3889
3902
                                                                        ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr.callno]->peercapability & iax_capability);
3890
3903
                                                                        send_command_final(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_REJECT, 0, "Unable to negotiate codec", strlen("Unable to negotiate codec"), -1);
3891
 
                                                                        ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible  with our capability 0x%x.\n", inet_ntoa(sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iax_capability);
 
3904
                                                                        ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible  with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iax_capability);
3892
3905
                                                                        iaxs[fr.callno]->alreadygone = 1;
3893
3906
                                                                        break;
3894
3907
                                                                }
3902
3915
                                                                iaxs[fr.callno]->state |= IAX_STATE_STARTED;
3903
3916
                                                                if (option_verbose > 2) 
3904
3917
                                                                        ast_verbose(VERBOSE_PREFIX_3 "Accepting unauthenticated call from %s, requested format = %d, actual format = %d\n", 
3905
 
                                                                                inet_ntoa(sin.sin_addr), iaxs[fr.callno]->peerformat,format);
 
3918
                                                                                ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat,format);
3906
3919
                                                                if(!(c = ast_iax_new(iaxs[fr.callno], AST_STATE_RING, format)))
3907
3920
                                                                        iax_destroy_nolock(fr.callno);
3908
3921
                                                        } else {
3909
3922
                                                                iaxs[fr.callno]->state |= IAX_STATE_TBD;
3910
3923
                                                                /* If this is a TBD call, we're ready but now what...  */
3911
3924
                                                                if (option_verbose > 2)
3912
 
                                                                        ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", inet_ntoa(sin.sin_addr));
 
3925
                                                                        ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr));
3913
3926
                                                        }
3914
3927
                                                }
3915
3928
                                        }
3926
3939
                                        mm = ast_matchmore_extension(NULL, iaxs[fr.callno]->context, (char *)f.data, 1, iaxs[fr.callno]->callerid);
3927
3940
                                        /* Must be started */
3928
3941
                                        if (ast_exists_extension(NULL, iaxs[fr.callno]->context, (char *)f.data, 1, iaxs[fr.callno]->callerid)) {
3929
 
                                                strcpy(rel0, "exists");
 
3942
                                                strncpy(rel0, "exists", sizeof(rel0) - 1);
3930
3943
                                        } else if (ast_canmatch_extension(NULL, iaxs[fr.callno]->context, (char *)f.data, 1, iaxs[fr.callno]->callerid)) {
3931
 
                                                strcpy(rel0, "canexist");
 
3944
                                                strncpy(rel0, "canexist", sizeof(rel0) - 1);
3932
3945
                                        } else {
3933
 
                                                strcpy(rel0, "nonexistant");
 
3946
                                                strncpy(rel0, "nonexistant", sizeof(rel0) - 1);
3934
3947
                                        }
3935
3948
                                        snprintf(rel1, sizeof(rel1), "number=%s;status=%s;ignorepat=%s;expirey=%d;matchmore=%s;",
3936
3949
                                                (char *)f.data, rel0,
3948
3961
                                if (f.data)
3949
3962
                                        ((char *)f.data)[f.datalen] = '\0';
3950
3963
                                if (iaxs[fr.callno]->owner)
3951
 
                                        ast_log(LOG_WARNING, "Call rejected by %s: %s\n", inet_ntoa(iaxs[fr.callno]->addr.sin_addr), (char *)f.data);
 
3964
                                        ast_log(LOG_WARNING, "Call rejected by %s: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr.sin_addr), (char *)f.data);
3952
3965
                                iaxs[fr.callno]->error = EPERM;
3953
3966
                                ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", fr.callno);
3954
3967
                                iax_destroy_nolock(fr.callno);
3967
3980
                                                iaxs[fr.callno]->peerformat = iax_capability;
3968
3981
                                }
3969
3982
                                if (option_verbose > 2)
3970
 
                                        ast_verbose(VERBOSE_PREFIX_3 "Call accepted by %s (format %s)\n", inet_ntoa(iaxs[fr.callno]->addr.sin_addr), ast_getformatname(iaxs[fr.callno]->peerformat));
 
3983
                                        ast_verbose(VERBOSE_PREFIX_3 "Call accepted by %s (format %s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr.sin_addr), ast_getformatname(iaxs[fr.callno]->peerformat));
3971
3984
                                if (!(iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability)) {
3972
3985
                                        send_command_final(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_REJECT, 0, "Unable to negotiate codec", strlen("Unable to negotiate codec"), -1);
3973
 
                                        ast_log(LOG_NOTICE, "Rejected call to %s, format 0x%x incompatible with our capability 0x%x.\n", inet_ntoa(sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->capability);
 
3986
                                        ast_log(LOG_NOTICE, "Rejected call to %s, format 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->capability);
3974
3987
                                } else {
3975
3988
                                        iaxs[fr.callno]->state |= IAX_STATE_STARTED;
3976
3989
                                        if (iaxs[fr.callno]->owner) {
4057
4070
                                        /* A little strange -- We have to actually go through the motions of
4058
4071
                                           delivering the packet.  In the very last step, it will be properly
4059
4072
                                           handled by do_deliver */
4060
 
                                        snprintf(src, sizeof(src), "LAGRQ-IAX/%s/%d", inet_ntoa(sin.sin_addr),fr.callno);
 
4073
                                        snprintf(src, sizeof(src), "LAGRQ-IAX/%s/%d", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr),fr.callno);
4061
4074
                                        f.src = src;
4062
4075
                                        f.mallocd = 0;
4063
4076
                                        f.offset = 0;
4077
4090
                                if (authenticate_reply(iaxs[fr.callno], &iaxs[fr.callno]->addr, (char *)f.data, iaxs[fr.callno]->secret, iaxs[fr.callno]->outkey)) {
4078
4091
                                        ast_log(LOG_WARNING, 
4079
4092
                                                "I don't know how to authenticate %s to %s\n", 
4080
 
                                                (char *)f.data, inet_ntoa(iaxs[fr.callno]->addr.sin_addr));
 
4093
                                                (char *)f.data, ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr.sin_addr));
4081
4094
                                }
4082
4095
                                break;
4083
4096
                        case AST_IAX_COMMAND_AUTHREP:
4088
4101
                                }
4089
4102
                                ((char *)f.data)[f.datalen] = '\0';
4090
4103
                                if (authenticate_verify(iaxs[fr.callno], (char *)f.data)) {
4091
 
                                        ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", inet_ntoa(iaxs[fr.callno]->addr.sin_addr), iaxs[fr.callno]->username);
 
4104
                                        ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr.sin_addr), iaxs[fr.callno]->username);
4092
4105
                                        send_command_final(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_REJECT, 0, "No authority found", strlen("No authority found"), -1);
4093
4106
                                        break;
4094
4107
                                }
4095
4108
                                /* This might re-enter the IAX code and need the lock */
4096
4109
                                exists = ast_exists_extension(NULL, iaxs[fr.callno]->context, iaxs[fr.callno]->exten, 1, iaxs[fr.callno]->callerid);
4097
4110
                                if (strcmp(iaxs[fr.callno]->exten, "TBD") && !exists) {
4098
 
                                        ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", inet_ntoa(sin.sin_addr), iaxs[fr.callno]->exten, iaxs[fr.callno]->context);
 
4111
                                        ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->exten, iaxs[fr.callno]->context);
4099
4112
                                        send_command_final(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_REJECT, 0, "No such context/extension", strlen("No such context/extension"), -1);
4100
4113
                                } else {
4101
4114
                                        /* Select an appropriate format */
4104
4117
                                                ast_log(LOG_DEBUG, "We don't do requested format %s, falling back to peer capability %d\n", ast_getformatname(iaxs[fr.callno]->peerformat), iaxs[fr.callno]->peercapability);
4105
4118
                                                format = iaxs[fr.callno]->peercapability & iax_capability;
4106
4119
                                                if (!format) {
4107
 
                                                        ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible  with our capability 0x%x.\n", inet_ntoa(sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iax_capability);
 
4120
                                                        ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible  with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iax_capability);
4108
4121
                                                        send_command_final(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_REJECT, 0, "Unable to negotiate codec", strlen("Unable to negotiate codec"), -1);
4109
4122
                                                } else {
4110
4123
                                                        /* Pick one... */
4111
4124
                                                        format = ast_best_codec(iaxs[fr.callno]->peercapability & iax_capability);
4112
4125
                                                        if (!format) {
4113
4126
                                                                ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr.callno]->peercapability & iax_capability);
4114
 
                                                                ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible  with our capability 0x%x.\n", inet_ntoa(sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iax_capability);
 
4127
                                                                ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible  with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iax_capability);
4115
4128
                                                                send_command_final(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_REJECT, 0, "Unable to negotiate codec", strlen("Unable to negotiate codec"), -1);
4116
4129
                                                        }
4117
4130
                                                }
4124
4137
                                                        iaxs[fr.callno]->state |= IAX_STATE_STARTED;
4125
4138
                                                        if (option_verbose > 2) 
4126
4139
                                                                ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s, requested format = %d, actual format = %d\n", 
4127
 
                                                                        inet_ntoa(sin.sin_addr), iaxs[fr.callno]->peerformat,format);
 
4140
                                                                        ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat,format);
4128
4141
                                                        iaxs[fr.callno]->state |= IAX_STATE_STARTED;
4129
4142
                                                        if(!(c = ast_iax_new(iaxs[fr.callno], AST_STATE_RING, format)))
4130
4143
                                                                iax_destroy_nolock(fr.callno);
4132
4145
                                                        iaxs[fr.callno]->state |= IAX_STATE_TBD;
4133
4146
                                                        /* If this is a TBD call, we're ready but now what...  */
4134
4147
                                                        if (option_verbose > 2)
4135
 
                                                                ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", inet_ntoa(sin.sin_addr));
 
4148
                                                                ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr));
4136
4149
                                                }
4137
4150
                                        }
4138
4151
                                }
4143
4156
                                        iaxs[fr.callno]->state &= ~IAX_STATE_TBD;
4144
4157
                                        strncpy(iaxs[fr.callno]->exten, (char *)f.data, sizeof(iaxs[fr.callno]->exten)-1);      
4145
4158
                                        if (!ast_exists_extension(NULL, iaxs[fr.callno]->context, iaxs[fr.callno]->exten, 1, iaxs[fr.callno]->callerid)) {
4146
 
                                                ast_log(LOG_NOTICE, "Rejected dial attempt from %s, request '%s@%s' does not exist\n", inet_ntoa(sin.sin_addr), iaxs[fr.callno]->exten, iaxs[fr.callno]->context);
 
4159
                                                ast_log(LOG_NOTICE, "Rejected dial attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->exten, iaxs[fr.callno]->context);
4147
4160
                                                send_command_final(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_REJECT, 0, "No such context/extension", strlen("No such context/extension"), -1);
4148
4161
                                        } else {
4149
4162
                                                iaxs[fr.callno]->state |= IAX_STATE_STARTED;
4150
4163
                                                if (option_verbose > 2) 
4151
 
                                                        ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", inet_ntoa(sin.sin_addr), iaxs[fr.callno]->peerformat);
 
4164
                                                        ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat);
4152
4165
                                                iaxs[fr.callno]->state |= IAX_STATE_STARTED;
4153
4166
                                                if(!(c = ast_iax_new(iaxs[fr.callno], AST_STATE_RING, iaxs[fr.callno]->peerformat)))
4154
4167
                                                        iax_destroy_nolock(fr.callno);
4302
4315
                return 1;
4303
4316
        }
4304
4317
        /* Common things */
4305
 
        snprintf(src, sizeof(src), "IAX/%s/%d", inet_ntoa(sin.sin_addr),fr.callno);     f.src = src;
 
4318
        snprintf(src, sizeof(src), "IAX/%s/%d", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr),fr.callno);   f.src = src;
4306
4319
        f.mallocd = 0;
4307
4320
        f.offset = 0;
4308
4321
        fr.f = &f;
4535
4548
 
4536
4549
static int start_network_thread(void)
4537
4550
{
4538
 
        return pthread_create(&netthreadid, NULL, network_thread, NULL);
 
4551
        return ast_pthread_create(&netthreadid, NULL, network_thread, NULL);
4539
4552
}
4540
4553
 
4541
4554
static struct iax_context *build_context(char *context)
4659
4672
                        } else if (!strcasecmp(v->name, "sendani")) {
4660
4673
                                peer->sendani = ast_true(v->value);
4661
4674
                        } else if (!strcasecmp(v->name, "inkeys")) {
4662
 
                                strncpy(peer->inkeys, v->value, sizeof(peer->inkeys));
 
4675
                                strncpy(peer->inkeys, v->value, sizeof(peer->inkeys) - 1);
4663
4676
                        } else if (!strcasecmp(v->name, "outkey")) {
4664
 
                                strncpy(peer->outkey, v->value, sizeof(peer->outkey));
 
4677
                                strncpy(peer->outkey, v->value, sizeof(peer->outkey) - 1);
4665
4678
                        } else if (!strcasecmp(v->name, "qualify")) {
4666
4679
                                if (!strcasecmp(v->value, "no")) {
4667
4680
                                        peer->maxms = 0;
4676
4689
                        v=v->next;
4677
4690
                }
4678
4691
                if (!strlen(peer->methods))
4679
 
                        strcpy(peer->methods, "md5,plaintext");
 
4692
                        strncpy(peer->methods, "md5,plaintext", sizeof(peer->methods) - 1);
4680
4693
                peer->delme = 0;
4681
4694
        }
4682
4695
        return peer;
4721
4734
                                        user->amaflags = format;
4722
4735
                                }
4723
4736
                        } else if (!strcasecmp(v->name, "inkeys")) {
4724
 
                                strncpy(user->inkeys, v->value, sizeof(user->inkeys));
 
4737
                                strncpy(user->inkeys, v->value, sizeof(user->inkeys) - 1);
4725
4738
                        } //else if (strcasecmp(v->name,"type"))
4726
4739
                        //      ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
4727
4740
                        v = v->next;
5371
5384
 
5372
5385
int unload_module()
5373
5386
{
 
5387
        int x;
 
5388
        for (x=0;x<AST_IAX_MAX_CALLS;x++)
 
5389
                ast_mutex_destroy(&iaxsl[x]);
 
5390
        ast_mutex_destroy(&iaxq.lock);
 
5391
        ast_mutex_destroy(&userl.lock);
 
5392
        ast_mutex_destroy(&peerl.lock);
5374
5393
        return __unload_module();
5375
5394
}
5376
5395
 
5381
5400
        int x;
5382
5401
        struct iax_registry *reg;
5383
5402
        struct iax_peer *peer;
 
5403
        char iabuf[INET_ADDRSTRLEN];
5384
5404
        
5385
5405
        struct sockaddr_in sin;
5386
5406
        
5405
5425
        ast_mutex_init(&iaxq.lock);
5406
5426
        ast_mutex_init(&userl.lock);
5407
5427
        ast_mutex_init(&peerl.lock);
5408
 
        ast_mutex_init(&dpcache_lock);
5409
5428
 
5410
5429
        ast_cli_register(&cli_show_users);
5411
5430
        ast_cli_register(&cli_show_channels);
5432
5451
                return -1;
5433
5452
        }
5434
5453
        if (bind(netsocket,(struct sockaddr *)&sin, sizeof(sin))) {
5435
 
                ast_log(LOG_ERROR, "Unable to bind to %s port %d: %s\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), strerror(errno));
 
5454
                ast_log(LOG_ERROR, "Unable to bind to %s port %d: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port), strerror(errno));
5436
5455
                close(netsocket);
5437
5456
                netsocket = -1;
5438
5457
                return -1;
5462
5481
        if (!res) {
5463
5482
                res = start_network_thread();
5464
5483
                if (option_verbose > 1) 
5465
 
                        ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening on %s port %d\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
 
5484
                        ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening on %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
5466
5485
        } else {
5467
5486
                ast_log(LOG_ERROR, "Unable to start network thread\n");
5468
5487
                close(netsocket);