2 * Asterisk -- A telephony toolkit for Linux.
4 * Implementation of Inter-Asterisk eXchange
6 * Copyright (C) 1999, Mark Spencer
8 * Mark Spencer <markster@linux-support.net>
10 * This program is free software, distributed under the terms of
11 * the GNU General Public License
14 #include <asterisk/frame.h>
15 #include <asterisk/channel.h>
16 #include <asterisk/channel_pvt.h>
17 #include <asterisk/logger.h>
18 #include <asterisk/module.h>
19 #include <asterisk/pbx.h>
20 #include <asterisk/sched.h>
21 #include <asterisk/io.h>
22 #include <asterisk/config.h>
23 #include <asterisk/options.h>
24 #include <asterisk/cli.h>
25 #include <asterisk/translate.h>
26 #include <asterisk/md5.h>
27 #include <arpa/inet.h>
28 #include <sys/socket.h>
29 #include <netinet/in.h>
31 #include <sys/signal.h>
41 #define DEFAULT_RETRY_TIME 1000
42 #define MEMORY_SIZE 100
43 #define DEFAULT_DROP 3
45 /* If you want to use the simulator, then define IAX_SIMULATOR. */
50 static char *desc = "Inter Asterisk eXchange";
51 static char *tdesc = "Inter Asterisk eXchange Drver";
52 static char *type = "IAX";
53 static char *config = "iax.conf";
55 static char context[80] = "default";
57 static int max_retries = 4;
58 static int ping_time = 20;
59 static int lagrq_time = 10;
60 static int nextcallno = 0;
61 static int maxjitterbuffer=4000;
63 static int netsocket = -1;
66 static pthread_mutex_t usecnt_lock = PTHREAD_MUTEX_INITIALIZER;
67 static pthread_mutex_t iaxs_lock = PTHREAD_MUTEX_INITIALIZER;
70 #define IAX_CAPABILITY_FULLBANDWIDTH 0x7FFFFFFF
72 #define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
73 ~AST_FORMAT_SLINEAR & \
77 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
81 #define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
84 static struct io_context *io;
85 static struct sched_context *sched;
87 static int iax_capability = IAX_CAPABILITY_FULLBANDWIDTH;
89 static int iax_dropcount = DEFAULT_DROP;
91 static int use_jitterbuffer = 1;
93 static pthread_t netthreadid;
95 #define IAX_STATE_STARTED (1 << 0)
96 #define IAX_STATE_AUTHENTICATED (1 << 1)
98 #define IAX_SENSE_DENY 0
99 #define IAX_SENSE_ALLOW 1
102 /* Host access rule */
103 struct in_addr netaddr;
104 struct in_addr netmask;
110 char context[AST_MAX_EXTENSION];
111 struct iax_context *next;
119 struct iax_context *contexts;
120 struct iax_user *next;
127 struct sockaddr_in addr;
131 /* Dynamic Registration fields */
133 struct sockaddr_in defaddr;
136 struct timeval nexpire;
139 struct iax_peer *next;
142 /* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
143 #define MIN_RETRY_TIME 10
144 #define MAX_RETRY_TIME 10000
145 #define MAX_JITTER_BUFFER 50
147 /* If we have more than this much excess real jitter buffer, srhink it. */
148 static int max_jitter_buffer = MAX_JITTER_BUFFER;
150 struct chan_iax_pvt {
151 /* Pipes for communication. pipe[1] belongs to the
152 network thread (write), and pipe[0] belongs to the individual
155 /* Last received voice format */
157 /* Last sent voice format */
159 /* Last received timestamp */
161 /* Last sent timestamp - never send the same timestamp twice in a single call */
162 unsigned int lastsent;
164 unsigned int pingtime;
166 struct sockaddr_in addr;
167 /* Our call number */
171 /* Peer supported formats */
173 /* timeval that we base our transmission on */
174 struct timeval offset;
175 /* timeval that we base our delivery on */
176 struct timeval rxcore;
177 /* Historical delivery time */
178 int history[MEMORY_SIZE];
179 /* Current base jitterbuffer */
181 /* Current jitter measure */
185 /* Error, as discovered by the manager */
187 /* Onwer if we have one */
188 struct ast_channel *owner;
189 /* What's our state? */
191 /* Next outgoing sequence number */
192 unsigned short oseqno;
193 /* Next incoming sequence number */
194 unsigned short iseqno;
197 /* Default Context */
199 /* Caller ID if available */
203 /* Requested Extension */
204 char exten[AST_MAX_EXTENSION];
205 /* Expected Username */
207 /* Expected Secret */
209 /* permitted authentication methods */
215 struct ast_iax_frame {
216 /* Actual, isolated frame */
218 /* /Our/ call number */
220 /* Start of raw frame (outgoing only) */
222 /* Length of frame (outgoing only) */
224 /* How many retries so far? */
226 /* Outgoing relative timestamp (ms) */
228 /* How long to wait before retrying */
230 /* Are we received out of order? */
232 /* Have we been sent at all yet? */
234 /* Packet sequence number */
237 struct ast_iax_frame *next;
238 struct ast_iax_frame *prev;
241 static struct ast_iax_queue {
242 struct ast_iax_frame *head;
243 struct ast_iax_frame *tail;
245 pthread_mutex_t lock;
248 static struct ast_user_list {
249 struct iax_user *users;
250 pthread_mutex_t lock;
253 static struct ast_peer_list {
254 struct iax_peer *peers;
255 pthread_mutex_t lock;
258 /* XXX We probably should use a mutex when working with this XXX */
259 static struct chan_iax_pvt *iaxs[AST_IAX_MAX_CALLS];
261 static int send_command(struct chan_iax_pvt *, char, int, unsigned int, char *, int, int);
263 static unsigned int calc_timestamp(struct chan_iax_pvt *p, unsigned int ts);
265 static int send_ping(void *data)
267 int callno = (long)data;
269 send_command(iaxs[callno], AST_FRAME_IAX, AST_IAX_COMMAND_PING, 0, NULL, 0, -1);
275 static int send_lagrq(void *data)
277 int callno = (long)data;
279 send_command(iaxs[callno], AST_FRAME_IAX, AST_IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
285 static unsigned char compress_subclass(int subclass)
289 /* If it's 128 or smaller, just return it */
290 if (subclass < AST_FLAG_SC_LOG)
292 /* Otherwise find its power */
293 for (x = 0; x < AST_MAX_SHIFT; x++) {
294 if (subclass & (1 << x)) {
296 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
302 return power | AST_FLAG_SC_LOG;
305 static int uncompress_subclass(unsigned char csub)
307 /* If the SC_LOG flag is set, return 2^csub otherwise csub */
308 if (csub & AST_FLAG_SC_LOG)
309 return 1 << (csub & ~AST_FLAG_SC_LOG & AST_MAX_SHIFT);
314 static struct chan_iax_pvt *new_iax(void)
316 struct chan_iax_pvt *tmp;
317 tmp = malloc(sizeof(struct chan_iax_pvt));
319 memset(tmp, 0, sizeof(struct chan_iax_pvt));
320 /* On my linux system, pipe's are more than 2x as fast as socketpairs */
321 if (pipe(tmp->pipe)) {
322 ast_log(LOG_WARNING, "Unable to create pipe: %s\n", strerror(errno));
327 tmp->peercallno = -1;
328 /* strncpy(tmp->context, context, sizeof(tmp->context)); */
329 strncpy(tmp->exten, "s", sizeof(tmp->exten));
334 static int get_timelen(struct ast_frame *f)
337 switch(f->subclass) {
338 case AST_FORMAT_G723_1:
344 case AST_FORMAT_SLINEAR:
345 timelen = f->datalen / 8;
347 case AST_FORMAT_LPC10:
349 timelen += ((char *)(f->data))[7] & 0x1;
352 ast_log(LOG_WARNING, "Don't know how to calculate timelen on %d packets\n", f->subclass);
358 static struct ast_iax_frame *iaxfrdup(struct ast_iax_frame *fr)
360 /* Malloc() a copy of a frame */
361 struct ast_iax_frame *new = malloc(sizeof(struct ast_iax_frame));
363 memcpy(new, fr, sizeof(struct ast_iax_frame));
368 static struct ast_iax_frame *iaxfrdup2(struct ast_iax_frame *fr, int ch)
370 /* Malloc() a copy of a frame */
371 struct ast_iax_frame *new = malloc(sizeof(struct ast_iax_frame));
373 memcpy(new, fr, sizeof(struct ast_iax_frame));
374 new->f = ast_frdup(fr->f);
375 /* Copy full header */
377 memcpy(new->f->data - sizeof(struct ast_iax_full_hdr),
378 fr->f->data - sizeof(struct ast_iax_full_hdr),
379 sizeof(struct ast_iax_full_hdr));
380 /* Grab new data pointer */
381 new->data = new->f->data - (fr->f->data - fr->data);
390 #define NEW_PREVENT 0
394 static int find_callno(short callno, short dcallno ,struct sockaddr_in *sin, int new)
399 if (new <= NEW_ALLOW) {
400 /* Look for an existing connection first */
401 for (x=0;x<AST_IAX_MAX_CALLS;x++) {
403 /* Look for an exact match */
404 if ((sin->sin_port == iaxs[x]->addr.sin_port) &&
405 (sin->sin_addr.s_addr == iaxs[x]->addr.sin_addr.s_addr) &&
406 ((callno == iaxs[x]->peercallno) || /* Our expected source call number is the same */
407 ((dcallno == x) && (iaxs[x]->peercallno = -1))
408 /* We have no expected source number, and the destination is right */
416 if ((res < 0) && (new >= NEW_ALLOW)) {
417 /* Create a new one */
419 for (x = nextcallno + 1; iaxs[x] && (x != start); x = (x + 1) % AST_IAX_MAX_CALLS)
421 ast_log(LOG_WARNING, "Unable to accept more calls\n");
427 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x);
428 iaxs[x]->addr.sin_port = sin->sin_port;
429 iaxs[x]->addr.sin_family = sin->sin_family;
430 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
431 iaxs[x]->peercallno = callno;
433 iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
434 ast_sched_add(sched, ping_time * 1000, send_ping, (void *)x);
435 ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)x);
437 ast_log(LOG_DEBUG, "Out of memory\n");
444 static int iax_send(struct chan_iax_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno);
446 static int do_deliver(void *data)
448 /* Just deliver the packet by writing it to half of the pipe. */
449 struct ast_iax_frame *fr = data;
451 if (iaxs[fr->callno]) {
452 if (fr->f->frametype == AST_FRAME_IAX) {
453 /* We have to treat some of these packets specially because
454 they're LAG measurement packets */
455 if (fr->f->subclass == AST_IAX_COMMAND_LAGRQ) {
456 /* If we got a queued request, build a reply and send it */
457 fr->f->subclass = AST_IAX_COMMAND_LAGRP;
458 iax_send(iaxs[fr->callno], fr->f, fr->ts, -1);
459 } else if (fr->f->subclass == AST_IAX_COMMAND_LAGRP) {
460 /* This is a reply we've been given, actually measure the difference */
461 ts = calc_timestamp(iaxs[fr->callno], 0);
462 iaxs[fr->callno]->lag = ts - fr->ts;
465 ast_fr_fdwrite(iaxs[fr->callno]->pipe[1], fr->f);
468 /* Free the packet */
470 /* And our iax frame */
472 /* And don't run again */
476 static int handle_error()
478 /* XXX Ideally we should figure out why an error occured and then abort those
479 rather than continuing to try. Unfortunately, the published interface does
480 not seem to work XXX */
482 struct sockaddr_in *sin;
485 struct sock_extended_err e;
490 m.msg_controllen = sizeof(e);
492 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
494 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
496 if (m.msg_controllen) {
497 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
499 ast_log(LOG_WARNING, "Receive error from %s\n", inet_ntoa(sin->sin_addr));
501 ast_log(LOG_WARNING, "No address detected??\n");
503 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
511 static int __send_packet(struct ast_iax_frame *f)
513 static int send_packet(struct ast_iax_frame *f)
518 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));
519 /* Don't send if there was an error, but return error instead */
521 ast_log(LOG_WARNING, "Call number = %d\n", f->callno);
524 if (iaxs[f->callno]->error)
526 res = sendto(netsocket, f->data, f->datalen, 0, &iaxs[f->callno]->addr,
527 sizeof(iaxs[f->callno]->addr));
529 ast_log(LOG_WARNING, "Received error: %s\n", strerror(errno));
538 /* Average amount of delay in the connection */
539 static int average_delay = 0;
540 /* Permitted deviation either side of the average delay */
541 static int delay_deviation = 0;
542 /* Percent chance that a packet arrives O.K. */
543 static int reliability = 100;
545 static int iax_sim_calc_delay()
548 ms = average_delay - delay_deviation;
549 ms += ((float)(delay_deviation * 2)) * rand() / (RAND_MAX + 1.0);
552 if ((float)rand()/(RAND_MAX + 1.0) < ((float)reliability)/100)
558 static int d_send_packet(void *v)
560 struct ast_iax_frame *f = (struct ast_iax_frame *)v;
568 static int send_packet(struct ast_iax_frame *f)
570 struct ast_iax_frame *fn;
572 ms = iax_sim_calc_delay();
574 return __send_packet(f);
576 /* Make a completely independent frame, in case the other
577 is destroyed -- still doesn't make things like hangups
578 arrive if the main channel is destroyed, but close enough */
579 fn = iaxfrdup2(f, 1);
580 ast_sched_add(sched, ms, d_send_packet, fn);
581 } /* else we drop the packet */
585 static int iax_sim_set(int fd, int argc, char *argv[])
588 return RESULT_SHOWUSAGE;
589 if (!strcasecmp(argv[2], "delay"))
590 average_delay = atoi(argv[3]);
591 else if (!strcasecmp(argv[2], "deviation"))
592 delay_deviation = atoi(argv[3]);
593 else if (!strcasecmp(argv[2], "reliability"))
594 reliability = atoi(argv[3]);
596 return RESULT_SHOWUSAGE;
597 if (reliability > 100)
601 if (delay_deviation > average_delay)
602 delay_deviation = average_delay;
603 return RESULT_SUCCESS;
606 static char delay_usage[] =
607 "Usage: sim set delay <value>\n"
608 " Configure the IAX network simulator to generate average\n"
609 " delays equal to the specified value (in milliseconds).\n";
611 static char deviation_usage[] =
612 "Usage: sim set deviation <value>\n"
613 " Configures the IAX network simulator's deviation value.\n"
614 " The delays generated by the simulator will always be within\n"
615 " this value of milliseconds (postive or negative) of the \n"
618 static char reliability_usage[] =
619 "Usage: sim set reliability <value>\n"
620 " Configure the probability that a packet will be delivered.\n"
621 " The value specified is a percentage from 0 to 100\n";
623 static int iax_sim_show(int fd, int argc, char *argv[])
626 return RESULT_SHOWUSAGE;
627 ast_cli(fd, "Average Delay: %d ms\n", average_delay);
628 ast_cli(fd, "Delay Deviation: %d ms\n", delay_deviation);
629 ast_cli(fd, "Reliability: %d %\n", reliability);
630 return RESULT_SUCCESS;
633 static char sim_show_usage[] =
635 " Displays average delay, deviation, and reliability\n"
636 " used by the network simulator.\n";
638 static struct ast_cli_entry delay_cli =
639 { { "sim", "set", "delay", NULL }, iax_sim_set, "Sets simulated average delay", delay_usage };
640 static struct ast_cli_entry deviation_cli =
641 { { "sim", "set", "deviation", NULL }, iax_sim_set, "Sets simulated delay deviation", deviation_usage };
642 static struct ast_cli_entry reliability_cli =
643 { { "sim", "set", "reliability", NULL }, iax_sim_set, "Sets simulated reliability", reliability_usage };
644 static struct ast_cli_entry sim_show_cli =
645 { { "sim", "show", NULL }, iax_sim_show, "Displays simulation parameters", sim_show_usage };
649 static int attempt_transmit(void *data)
651 /* Attempt to transmit the frame to the remote peer */
653 struct ast_iax_frame *f = data;
655 /* Make sure this call is still active */
656 if (iaxs[f->callno]) {
657 if ((f->retries == -1) /* Already ACK'd */ ||
658 (f->retries >= max_retries) /* Too many attempts */) {
659 /* Record an error if we've transmitted too many times */
660 if (f->retries >= max_retries) {
661 ast_log(LOG_WARNING, "Max retries exceeded to host %s (type = %d, subclass = %d, ts=%d, seqno=%d)\n", inet_ntoa(iaxs[f->callno]->addr.sin_addr), f->f->frametype, f->f->subclass, f->ts, f->seqno);
662 iaxs[f->callno]->error = ETIMEDOUT;
663 /* Send a bogus frame to wake up the waiting process */
664 write(iaxs[f->callno]->pipe[1], &zero, 1);
666 /* Don't attempt delivery, just remove it from the queue */
667 pthread_mutex_lock(&iaxq.lock);
669 f->prev->next = f->next;
673 f->next->prev = f->prev;
677 pthread_mutex_unlock(&iaxq.lock);
679 /* Attempt transmission */
682 /* Try again later after 10 times as long */
684 if (f->retrytime > MAX_RETRY_TIME)
685 f->retrytime = MAX_RETRY_TIME;
686 ast_sched_add(sched, f->retrytime, attempt_transmit, f);
690 /* Do not try again */
694 static int iax_set_jitter(int fd, int argc, char *argv[])
696 if ((argc != 4) && (argc != 5))
697 return RESULT_SHOWUSAGE;
699 max_jitter_buffer = atoi(argv[3]);
700 if (max_jitter_buffer < 0)
701 max_jitter_buffer = 0;
704 pthread_mutex_lock(&iaxs_lock);
705 if ((atoi(argv[3]) >= 0) && (atoi(argv[3]) < AST_IAX_MAX_CALLS)) {
706 if (iaxs[atoi(argv[3])]) {
707 iaxs[atoi(argv[3])]->jitterbuffer = atoi(argv[4]);
708 if (iaxs[atoi(argv[3])]->jitterbuffer < 0)
709 iaxs[atoi(argv[3])]->jitterbuffer = 0;
711 ast_cli(fd, "No such call '%d'\n", atoi(argv[3]));
713 ast_cli(fd, "%d is not a valid call number\n", atoi(argv[3]));
714 pthread_mutex_unlock(&iaxs_lock);
717 return RESULT_SUCCESS;
720 static char jitter_usage[] =
721 "Usage: iax set jitter [callid] <value>\n"
722 " If used with a callid, it sets the jitter buffer to the given static\n"
723 "value (until its next calculation). If used without a callid, the value is used\n"
724 "to establish the maximum excess jitter buffer that is permitted before the jitter\n"
725 "buffer size is reduced.";
727 static struct ast_cli_entry cli_set_jitter =
728 { { "iax", "set", "jitter", NULL }, iax_set_jitter, "Sets IAX jitter buffer", jitter_usage };
730 static unsigned int calc_rxstamp(struct chan_iax_pvt *p);
732 static int schedule_delivery(struct ast_iax_frame *fr)
734 /* XXX FIXME: I should delay delivery with a sliding jitter buffer XXX */
736 int drops[MEMORY_SIZE];
737 int min, max=0, maxone=0,y,z, match;
738 /* ms is a measure of the "lateness" of the packet relative to the first
739 packet we received, which always has a lateness of 1. */
740 ms = calc_rxstamp(iaxs[fr->callno]) - fr->ts;
742 /* Rotate our history queue of "lateness". Don't worry about those initial
743 zeros because the first entry will always be zero */
744 for (x=0;x<MEMORY_SIZE - 1;x++)
745 iaxs[fr->callno]->history[x] = iaxs[fr->callno]->history[x+1];
746 /* Add a history entry for this one */
747 iaxs[fr->callno]->history[x] = ms;
749 /* Initialize the minimum to reasonable values. It's too much
750 work to do the same for the maximum, repeatedly */
751 min=iaxs[fr->callno]->history[0];
752 for (z=0;z < iax_dropcount + 1;z++) {
753 /* Start very pessimistic ;-) */
755 for (x=0;x<MEMORY_SIZE;x++) {
756 if (max < iaxs[fr->callno]->history[x]) {
757 /* We have a candidate new maximum value. Make
758 sure it's not in our drop list */
760 for (y=0;!match && (y<z);y++)
761 match |= (drops[y] == x);
763 /* It's not in our list, use it as the new maximum */
764 max = iaxs[fr->callno]->history[x];
770 /* On our first pass, find the minimum too */
771 if (min > iaxs[fr->callno]->history[x])
772 min = iaxs[fr->callno]->history[x];
779 /* Just for reference, keep the "jitter" value, the difference between the
780 earliest and the latest. */
781 iaxs[fr->callno]->jitter = max - min;
783 /* If our jitter buffer is too big (by a significant margin), then we slowly
784 shrink it by about 1 ms each time to avoid letting the change be perceived */
785 if (max < iaxs[fr->callno]->jitterbuffer - max_jitter_buffer)
786 iaxs[fr->callno]->jitterbuffer -= 2;
789 /* Constrain our maximum jitter buffer appropriately */
790 if (max > min + maxjitterbuffer) {
792 ast_log(LOG_DEBUG, "Constraining buffer from %d to %d + %d\n", max, min , maxjitterbuffer);
793 max = min + maxjitterbuffer;
797 /* If our jitter buffer is smaller than our maximum delay, grow the jitter
798 buffer immediately to accomodate it (and a little more). */
799 if (max > iaxs[fr->callno]->jitterbuffer)
800 iaxs[fr->callno]->jitterbuffer = max
801 /* + ((float)iaxs[fr->callno]->jitter) * 0.1 */;
805 ast_log(LOG_DEBUG, "min = %d, max = %d, jb = %d, lateness = %d\n", min, max, iaxs[fr->callno]->jitterbuffer, ms);
807 /* Subtract the lateness from our jitter buffer to know how long to wait
808 before sending our packet. */
809 ms = iaxs[fr->callno]->jitterbuffer - ms;
811 if (!use_jitterbuffer)
816 ast_log(LOG_DEBUG, "Calculated ms is %d\n", ms);
817 /* Don't deliver it more than 4 ms late */
818 if ((ms > -4) || (fr->f->frametype != AST_FRAME_VOICE)) {
822 /* Free the packet */
824 /* And our iax frame */
829 ast_log(LOG_DEBUG, "Scheduling delivery in %d ms\n", ms);
830 ast_sched_add(sched, ms, do_deliver, fr);
835 static int iax_transmit(struct ast_iax_frame *fr)
837 /* Lock the queue and place this packet at the end */
840 /* By setting this to 0, the network thread will send it for us, and
841 queue retransmission if necessary */
843 pthread_mutex_lock(&iaxq.lock);
850 iaxq.tail->next = fr;
851 fr->prev = iaxq.tail;
855 pthread_mutex_unlock(&iaxq.lock);
856 /* Wake up the network thread */
857 pthread_kill(netthreadid, SIGURG);
863 static int iax_digit(struct ast_channel *c, char digit)
865 return send_command(c->pvt->pvt, AST_FRAME_DTMF, digit, 0, NULL, 0, -1);
868 static int iax_sendtext(struct ast_channel *c, char *text)
871 return send_command(c->pvt->pvt, AST_FRAME_TEXT,
872 0, 0, text, strlen(text) + 1, -1);
875 static int create_addr(struct sockaddr_in *sin, char *peer)
879 sin->sin_family = AF_INET;
880 pthread_mutex_lock(&peerl.lock);
883 if (!strcasecmp(p->name, peer)) {
884 sin->sin_addr = p->addr.sin_addr;
885 sin->sin_port = p->addr.sin_port;
890 pthread_mutex_unlock(&peerl.lock);
892 hp = gethostbyname(peer);
894 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
895 sin->sin_port = htons(AST_DEFAULT_IAX_PORTNO);
902 static int iax_call(struct ast_channel *c, char *dest, int timeout)
904 struct sockaddr_in sin;
910 char requeststr[256] = "";
911 char myrdest [5] = "s";
913 if ((c->state != AST_STATE_DOWN) && (c->state != AST_STATE_RESERVED)) {
914 ast_log(LOG_WARNING, "Line is already in use (%s)?\n", c->name);
917 strncpy(host, dest, sizeof(host));
919 /* If no destination extension specified, use 's' */
920 rdest = strtok(NULL, "/");
924 rcontext = strtok(NULL, "@");
926 username = strtok(NULL, "@");
928 /* Really the second argument is the host, not the username */
934 if (strtok(hname, ":")) {
936 portno = strtok(hname, ":");
938 if (create_addr(&sin, hname)) {
939 ast_log(LOG_WARNING, "No address associated with '%s'\n", hname);
943 sin.sin_port = htons(atoi(portno));
945 /* Now we build our request string */
946 #define MYSNPRINTF snprintf(requeststr + strlen(requeststr), sizeof(requeststr) - strlen(requeststr),
947 MYSNPRINTF "exten=%s;", rdest);
949 MYSNPRINTF "callerid=%s;", c->callerid);
951 MYSNPRINTF "dnid=%s;", c->dnid);
953 MYSNPRINTF "context=%s;", rcontext);
955 MYSNPRINTF "username=%s;", username);
956 MYSNPRINTF "formats=%d;", c->format);
957 MYSNPRINTF "version=%d;", AST_IAX_PROTO_VERSION);
958 /* Trim the trailing ";" */
959 if (strlen(requeststr))
960 requeststr[strlen(requeststr) - 1] = '\0';
961 /* Transmit the string in a "NEW" request */
962 if (option_verbose > 2)
963 ast_verbose(VERBOSE_PREFIX_3 "Calling using options '%s'\n", requeststr);
964 send_command((struct chan_iax_pvt *)c->pvt->pvt, AST_FRAME_IAX,
965 AST_IAX_COMMAND_NEW, 0, requeststr, strlen(requeststr) + 1, -1);
966 c->state = AST_STATE_RINGING;
970 static void iax_destroy(int callno)
973 struct chan_iax_pvt *pvt = iaxs[callno];
976 /* If there's an owner, prod it to give up */
977 write(pvt->pipe[1], &zero, 1);
987 static int iax_hangup(struct ast_channel *c) {
988 struct chan_iax_pvt *pvt = c->pvt->pvt;
989 /* Send the hangup unless we have had a transmission error */
991 send_command(pvt, AST_FRAME_IAX, AST_IAX_COMMAND_HANGUP, 0, NULL, 0, -1);
992 /* Wait for the network thread to transmit our command -- of course, if
993 it doesn't, that's okay too -- the other end will find out
994 soon enough, but it's a nicity if it can know now. */
997 pthread_mutex_lock(&iaxs_lock);
1000 pthread_mutex_lock(&usecnt_lock);
1003 ast_log(LOG_WARNING, "Usecnt < 0???\n");
1004 pthread_mutex_unlock(&usecnt_lock);
1005 ast_update_use_count();
1006 if (option_verbose > 2)
1007 ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
1008 iax_destroy(pvt->callno);
1009 pthread_mutex_unlock(&iaxs_lock);
1013 static struct ast_frame *iax_read(struct ast_channel *c)
1015 struct chan_iax_pvt *pvt = c->pvt->pvt;
1016 struct ast_frame *f;
1018 ast_log(LOG_DEBUG, "Connection closed, error: %s\n", strerror(pvt->error));
1021 f = ast_fr_fdread(pvt->pipe[0]);
1023 if ((f->frametype == AST_FRAME_CONTROL) &&
1024 (f->subclass == AST_CONTROL_ANSWER))
1025 c->state = AST_STATE_UP;
1030 static int iax_answer(struct ast_channel *c)
1032 struct chan_iax_pvt *pvt = c->pvt->pvt;
1034 ast_log(LOG_DEBUG, "Answering\n");
1035 return send_command(pvt, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
1038 static int iax_write(struct ast_channel *c, struct ast_frame *f);
1040 static struct ast_channel *ast_iax_new(struct chan_iax_pvt *i, int state)
1042 struct ast_channel *tmp;
1043 tmp = ast_channel_alloc();
1045 snprintf(tmp->name, sizeof(tmp->name), "IAX[%s:%d]/%d", inet_ntoa(i->addr.sin_addr), ntohs(i->addr.sin_port), i->callno);
1047 tmp->fd = i->pipe[0];
1048 /* We can support any format by default, until we get restricted */
1049 tmp->format = iax_capability;
1051 tmp->pvt->send_digit = iax_digit;
1052 tmp->pvt->send_text = iax_sendtext;
1053 tmp->pvt->call = iax_call;
1054 tmp->pvt->hangup = iax_hangup;
1055 tmp->pvt->answer = iax_answer;
1056 tmp->pvt->read = iax_read;
1057 tmp->pvt->write = iax_write;
1058 if (strlen(i->callerid))
1059 tmp->callerid = strdup(i->callerid);
1060 if (strlen(i->dnid))
1061 tmp->dnid = strdup(i->dnid);
1062 strncpy(tmp->context, i->context, sizeof(tmp->context));
1063 strncpy(tmp->exten, i->exten, sizeof(tmp->exten));
1066 pthread_mutex_lock(&usecnt_lock);
1068 pthread_mutex_unlock(&usecnt_lock);
1069 ast_update_use_count();
1070 if (state != AST_STATE_DOWN) {
1071 if (ast_pbx_start(tmp)) {
1072 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
1081 static unsigned int calc_timestamp(struct chan_iax_pvt *p, unsigned int ts)
1085 if (!p->offset.tv_sec && !p->offset.tv_usec)
1086 gettimeofday(&p->offset, NULL);
1087 /* If the timestamp is specified, just send it as is */
1090 gettimeofday(&tv, NULL);
1091 ms = (tv.tv_sec - p->offset.tv_sec) * 1000 + (tv.tv_usec - p->offset.tv_usec) / 1000;
1092 /* We never send the same timestamp twice, so fudge a little if we must */
1093 if (ms <= p->lastsent)
1094 ms = p->lastsent + 1;
1099 static unsigned int calc_rxstamp(struct chan_iax_pvt *p)
1101 /* Returns where in "receive time" we are */
1104 if (!p->rxcore.tv_sec && !p->rxcore.tv_usec)
1105 gettimeofday(&p->rxcore, NULL);
1106 gettimeofday(&tv, NULL);
1107 ms = (tv.tv_sec - p->offset.tv_sec) * 1000 + (tv.tv_usec - p->offset.tv_usec) / 1000;
1110 static int iax_send(struct chan_iax_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno)
1112 /* Queue a packet for delivery on a given private structure. Use "ts" for
1113 timestamp, or calculate if ts is 0 */
1114 struct ast_iax_full_hdr *fh;
1115 struct ast_iax_mini_hdr *mh;
1116 struct ast_iax_frame *fr;
1118 unsigned int lastsent;
1119 /* Allocate an ast_iax_frame */
1120 fr = malloc(sizeof(struct ast_iax_frame));
1122 ast_log(LOG_WARNING, "Out of memory\n");
1126 ast_log(LOG_WARNING, "No private structure for packet (%d)?\n", fr->callno);
1130 /* Isolate our frame for transmission */
1131 fr->f = ast_frdup(f);
1133 ast_log(LOG_WARNING, "Out of memory\n");
1137 if (fr->f->offset < sizeof(struct ast_iax_full_hdr)) {
1138 ast_log(LOG_WARNING, "Packet from '%s' not friendly\n", fr->f->src);
1142 lastsent = pvt->lastsent;
1143 fr->ts = calc_timestamp(pvt, ts);
1145 ast_log(LOG_WARNING, "timestamp is 0?\n");
1148 fr->callno = pvt->callno;
1149 if (((fr->ts & 0xFFFF0000L) != (lastsent & 0xFFFF0000L))
1150 /* High two bits of timestamp differ */ ||
1151 (fr->f->frametype != AST_FRAME_VOICE)
1152 /* or not a voice frame */ ||
1153 (fr->f->subclass != pvt->svoiceformat)
1154 /* or new voice format */ ) {
1155 /* We need a full frame */
1159 fr->seqno = pvt->oseqno++;
1160 fh = (struct ast_iax_full_hdr *)(fr->f->data - sizeof(struct ast_iax_full_hdr));
1161 fh->callno = htons(fr->callno | AST_FLAG_FULL);
1162 fh->ts = htonl(fr->ts);
1163 fh->seqno = htons(fr->seqno);
1164 fh->type = fr->f->frametype & 0xFF;
1165 fh->csub = compress_subclass(fr->f->subclass);
1167 fh->subclasshigh = (fr->f->subclass & 0xFF0000) >> 16;
1168 fh->subclasslow = htons(fr->f->subclass & 0xFFFF);
1170 fh->dcallno = htons(pvt->peercallno);
1171 fr->datalen = fr->f->datalen + sizeof(struct ast_iax_full_hdr);
1174 /* Retry after 2x the ping time has passed */
1175 fr->retrytime = pvt->pingtime * 2;
1176 if (fr->retrytime < MIN_RETRY_TIME)
1177 fr->retrytime = MIN_RETRY_TIME;
1178 if (fr->retrytime > MAX_RETRY_TIME)
1179 fr->retrytime = MAX_RETRY_TIME;
1180 /* Acks' don't get retried */
1181 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == AST_IAX_COMMAND_ACK))
1183 if (f->frametype == AST_FRAME_VOICE) {
1184 pvt->svoiceformat = f->subclass;
1186 res = iax_transmit(fr);
1188 /* Mini-frames have no sequence number */
1190 /* Mini frame will do */
1191 mh = (struct ast_iax_mini_hdr *)(fr->f->data - sizeof(struct ast_iax_mini_hdr));
1192 mh->callno = htons(fr->callno);
1193 mh->ts = htons(fr->ts & 0xFFFF);
1194 fr->datalen = fr->f->datalen + sizeof(struct ast_iax_mini_hdr);
1197 res = iax_transmit(fr);
1204 static int iax_show_users(int fd, int argc, char *argv[])
1206 #define FORMAT "%-15.15s %-15.15s %-15.15s %-15.15s %-5.5s\n"
1207 struct iax_user *user;
1209 return RESULT_SHOWUSAGE;
1210 pthread_mutex_lock(&userl.lock);
1211 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C");
1212 for(user=userl.users;user;user=user->next) {
1213 ast_cli(fd, FORMAT, user->name, user->secret, user->methods,
1214 user->contexts ? user->contexts->context : context,
1215 user->ha ? "Yes" : "No");
1217 pthread_mutex_unlock(&userl.lock);
1218 return RESULT_SUCCESS;
1222 static int iax_show_peers(int fd, int argc, char *argv[])
1224 #define FORMAT2 "%-15.15s %-15.15s %-15.15s %-15.15s %s\n"
1225 #define FORMAT "%-15.15s %-15.15s %-15.15s %-15.15s %d\n"
1226 struct iax_peer *peer;
1228 return RESULT_SHOWUSAGE;
1229 pthread_mutex_lock(&peerl.lock);
1230 ast_cli(fd, FORMAT2, "Name", "Username", "Host", "Mask", "Port");
1231 for (peer = peerl.peers;peer;peer = peer->next) {
1233 strncpy(nm, inet_ntoa(peer->mask), sizeof(nm));
1234 ast_cli(fd, FORMAT, peer->name,
1235 peer->username ? peer->username : "(Any)",
1236 peer->addr.sin_addr.s_addr ? inet_ntoa(peer->addr.sin_addr) : "(Any)",
1238 ntohs(peer->addr.sin_port));
1240 pthread_mutex_unlock(&peerl.lock);
1241 return RESULT_SUCCESS;
1246 static int iax_show_channels(int fd, int argc, char *argv[])
1248 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %s\n"
1249 #define FORMAT "%-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %d\n"
1252 return RESULT_SHOWUSAGE;
1253 pthread_mutex_lock(&iaxs_lock);
1254 ast_cli(fd, FORMAT2, "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "Format");
1255 for (x=0;x<AST_IAX_MAX_CALLS;x++)
1257 ast_cli(fd, FORMAT, inet_ntoa(iaxs[x]->addr.sin_addr),
1258 strlen(iaxs[x]->username) ? iaxs[x]->username : "(None)",
1259 iaxs[x]->callno, iaxs[x]->peercallno,
1260 iaxs[x]->oseqno, iaxs[x]->iseqno,
1263 iaxs[x]->voiceformat);
1264 pthread_mutex_unlock(&iaxs_lock);
1265 return RESULT_SUCCESS;
1270 static char show_users_usage[] =
1271 "Usage: iax show users\n"
1272 " Lists all users known to the IAX (Inter-Asterisk eXchange) subsystem.\n";
1274 static char show_channels_usage[] =
1275 "Usage: iax show channels\n"
1276 " Lists all currently active IAX channels.\n";
1278 static char show_peers_usage[] =
1279 "Usage: iax show peers\n"
1280 " Lists all known IAX peers.\n";
1282 static struct ast_cli_entry cli_show_users =
1283 { { "iax", "show", "users", NULL }, iax_show_users, "Show defined IAX users", show_users_usage };
1284 static struct ast_cli_entry cli_show_channels =
1285 { { "iax", "show", "channels", NULL }, iax_show_channels, "Show active IAX channels", show_channels_usage };
1286 static struct ast_cli_entry cli_show_peers =
1287 { { "iax", "show", "peers", NULL }, iax_show_peers, "Show defined IAX peers", show_peers_usage };
1289 static int iax_write(struct ast_channel *c, struct ast_frame *f)
1291 struct chan_iax_pvt *i = c->pvt->pvt;
1292 /* If there's an outstanding error, return failure now */
1294 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
1297 /* Don't waste bandwidth sending null frames */
1298 if (f->frametype == AST_FRAME_NULL)
1300 /* Simple, just queue for transmission */
1301 return iax_send(i, f, 0, -1);
1304 static int send_command(struct chan_iax_pvt *i, char type, int command, unsigned int ts, char *data, int datalen, int seqno)
1308 f.subclass = command;
1309 f.datalen = datalen;
1313 f.src = __FUNCTION__;
1315 return iax_send(i, &f, ts, seqno);
1318 static int apply_context(struct iax_context *con, char *context)
1321 if (!strcmp(con->context, context))
1328 static int apply_ha(struct iax_ha *ha, struct sockaddr_in *sin)
1330 /* Start optimistic */
1331 int res = IAX_SENSE_ALLOW;
1333 /* For each rule, if this address and the netmask = the net address
1334 apply the current rule */
1335 if ((sin->sin_addr.s_addr & ha->netmask.s_addr) == (ha->netaddr.s_addr))
1342 static int iax_getformats(int callno, char *orequest)
1346 strncpy(request, orequest, sizeof(request));
1347 var = strtok(request, ";");
1349 value = strchr(var, '=');
1353 if (!strcmp(var, "formats")) {
1354 iaxs[callno]->peerformats = atoi(value);
1356 ast_log(LOG_WARNING, "Unknown variable '%s' with value '%s'\n", var, value);
1358 var = strtok(NULL, ";");
1363 static int check_access(int callno, struct sockaddr_in *sin, char *orequest, int requestl)
1365 /* Start pessimistic */
1369 struct iax_user *user;
1371 strncpy(request, orequest, sizeof(request));
1374 var = strtok(request, ";");
1376 value = strchr(var, '=');
1380 if (!strcmp(var, "exten"))
1381 strncpy(iaxs[callno]->exten, value, sizeof(iaxs[callno]->exten));
1382 else if (!strcmp(var, "callerid"))
1383 strncpy(iaxs[callno]->callerid, value, sizeof(iaxs[callno]->callerid));
1384 else if (!strcmp(var, "dnid"))
1385 strncpy(iaxs[callno]->dnid, value, sizeof(iaxs[callno]->dnid));
1386 else if (!strcmp(var, "context"))
1387 strncpy(iaxs[callno]->context, value, sizeof(iaxs[callno]->context));
1388 else if (!strcmp(var, "username"))
1389 strncpy(iaxs[callno]->username, value, sizeof(iaxs[callno]->username));
1390 else if (!strcmp(var, "formats"))
1391 iaxs[callno]->peerformats = atoi(value);
1392 else if (!strcmp(var, "version"))
1393 version = atoi(value);
1395 ast_log(LOG_WARNING, "Unknown variable '%s' with value '%s'\n", var, value);
1397 var = strtok(NULL, ";");
1399 if (version > AST_IAX_PROTO_VERSION) {
1400 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
1401 inet_ntoa(sin->sin_addr), version);
1404 pthread_mutex_lock(&userl.lock);
1405 /* Search the userlist for a compatible entry, and fill in the rest */
1408 if ((!strlen(iaxs[callno]->username) || /* No username specified */
1409 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
1410 && (apply_ha(user->ha, sin) == IAX_SENSE_ALLOW) /* Access is permitted from this IP */
1411 && (!strlen(iaxs[callno]->context) || /* No context specified */
1412 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */
1413 /* We found our match (use the first) */
1415 /* Store the requested username if not specified */
1416 if (!strlen(iaxs[callno]->username))
1417 strncpy(iaxs[callno]->username, user->name, sizeof(iaxs[callno]->username));
1418 /* And use the default context */
1419 if (!strlen(iaxs[callno]->context)) {
1421 strncpy(iaxs[callno]->context, user->contexts->context, sizeof(iaxs[callno]->context));
1423 strncpy(iaxs[callno]->context, context, sizeof(iaxs[callno]->context));
1425 /* Copy the secret */
1426 strncpy(iaxs[callno]->secret, user->secret, sizeof(iaxs[callno]->secret));
1427 /* And the permitted authentication methods */
1428 strncpy(iaxs[callno]->methods, user->methods, sizeof(iaxs[callno]->methods));
1434 pthread_mutex_unlock(&userl.lock);
1438 static int raw_hangup(struct sockaddr_in *sin, short src, short dst)
1440 struct ast_iax_full_hdr fh;
1441 fh.callno = htons(src | AST_FLAG_FULL);
1442 fh.dcallno = htons(dst);
1445 fh.type = AST_FRAME_IAX;
1446 fh.csub = compress_subclass(AST_IAX_COMMAND_INVAL);
1448 ast_log(LOG_DEBUG, "Raw Hangup\n");
1449 return sendto(netsocket, &fh, sizeof(fh), 0, sin, sizeof(*sin));
1452 static int authenticate_request(struct chan_iax_pvt *p)
1454 char requeststr[256] = "";
1455 MYSNPRINTF "methods=%s;", p->methods);
1456 if (strstr(p->methods, "md5")) {
1457 /* Build the challenge */
1459 snprintf(p->challenge, sizeof(p->challenge), "%d", rand());
1460 MYSNPRINTF "challenge=%s;", p->challenge);
1462 MYSNPRINTF "username=%s;", p->username);
1463 if (strlen(requeststr))
1464 requeststr[strlen(requeststr) - 1] = '\0';
1465 return send_command(p, AST_FRAME_IAX, AST_IAX_COMMAND_AUTHREQ, 0, requeststr, strlen(requeststr) + 1, -1);
1468 static int authenticate_verify(struct chan_iax_pvt *p, char *orequest)
1470 char requeststr[256] = "";
1471 char *var, *value, request[256];
1472 char md5secret[256] = "";
1473 char secret[256] = "";
1477 if (!(p->state & IAX_STATE_AUTHENTICATED))
1479 strncpy(request, orequest, sizeof(request));
1480 var = strtok(request, ";");
1482 value = strchr(var, '=');
1486 if (!strcmp(var, "secret"))
1487 strncpy(secret, value, sizeof(secret));
1488 else if (!strcmp(var, "md5secret"))
1489 strncpy(md5secret, value, sizeof(md5secret));
1491 ast_log(LOG_WARNING, "Unknown variable '%s' with value '%s'\n", var, value);
1493 var = strtok(NULL, ";");
1495 if (strstr(p->methods, "md5")) {
1496 struct MD5Context md5;
1497 unsigned char digest[16];
1499 MD5Update(&md5, p->challenge, strlen(p->challenge));
1500 MD5Update(&md5, p->secret, strlen(p->secret));
1501 MD5Final(digest, &md5);
1502 /* If they support md5, authenticate with it. */
1504 MYSNPRINTF "%2.2x", digest[x]);
1505 if (!strcasecmp(requeststr, md5secret))
1507 } else if (strstr(p->methods, "plaintext")) {
1508 if (!strcmp(secret, p->secret))
1514 static int authenticate_reply(struct chan_iax_pvt *p, struct sockaddr_in *sin, char *orequest)
1516 struct iax_peer *peer;
1517 /* Start pessimistic */
1520 char methods[80] = "";
1521 char requeststr[256] = "";
1524 strncpy(request, orequest, sizeof(request));
1525 var = strtok(request, ";");
1527 value = strchr(var, '=');
1531 if (!strcmp(var, "username"))
1532 strncpy(p->username, value, sizeof(p->username));
1533 else if (!strcmp(var, "challenge"))
1534 strncpy(p->challenge, value, sizeof(p->challenge));
1535 else if (!strcmp(var, "methods"))
1536 strncpy(methods, value, sizeof(methods));
1538 ast_log(LOG_WARNING, "Unknown variable '%s' with value '%s'\n", var, value);
1540 var = strtok(NULL, ";");
1542 pthread_mutex_lock(&peerl.lock);
1545 if ((!strlen(p->peer) || !strcmp(p->peer, peer->name))
1546 /* No peer specified at our end, or this is the peer */
1547 && (!strlen(peer->username) || (!strcmp(peer->username, p->username)))
1548 /* No username specified in peer rule, or this is the right username */
1549 && (!peer->addr.sin_addr.s_addr || ((sin->sin_addr.s_addr & peer->mask.s_addr) == (peer->addr.sin_addr.s_addr & peer->mask.s_addr)))
1550 /* No specified host, or this is our host */
1552 /* We have a match, authenticate it. */
1554 if (strstr(methods, "md5")) {
1555 struct MD5Context md5;
1556 unsigned char digest[16];
1558 MD5Update(&md5, p->challenge, strlen(p->challenge));
1559 MD5Update(&md5, peer->secret, strlen(peer->secret));
1560 MD5Final(digest, &md5);
1561 /* If they support md5, authenticate with it. */
1562 MYSNPRINTF "md5secret=");
1564 MYSNPRINTF "%2.2x", digest[x]);
1566 } else if (strstr(methods, "plaintext")) {
1567 MYSNPRINTF "secret=%s;", peer->secret);
1570 if (strlen(requeststr))
1571 requeststr[strlen(requeststr)-1] = '\0';
1573 res = send_command(p, AST_FRAME_IAX, AST_IAX_COMMAND_AUTHREP, 0, requeststr, strlen(requeststr) + 1, -1);
1578 pthread_mutex_unlock(&peerl.lock);
1582 static int socket_read(int *id, int fd, short events, void *cbdata)
1584 struct sockaddr_in sin;
1586 int new = NEW_PREVENT;
1589 int len = sizeof(sin);
1591 struct ast_iax_full_hdr *fh = (struct ast_iax_full_hdr *)buf;
1592 struct ast_iax_mini_hdr *mh = (struct ast_iax_mini_hdr *)buf;
1593 struct ast_iax_frame fr, *cur;
1595 struct ast_channel *c;
1596 res = recvfrom(netsocket, buf, sizeof(buf), 0, &sin, &len);
1598 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
1602 if (res < sizeof(struct ast_iax_mini_hdr)) {
1603 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, sizeof(struct ast_iax_mini_hdr));
1606 if (ntohs(mh->callno) & AST_FLAG_FULL) {
1607 /* Get the destination call number */
1608 dcallno = ntohs(fh->dcallno);
1609 /* Retrieve the type and subclass */
1610 f.frametype = fh->type;
1611 f.subclass = uncompress_subclass(fh->csub);
1613 f.subclass = fh->subclasshigh << 16;
1614 f.subclass += ntohs(fh->subclasslow);
1616 if ((f.frametype == AST_FRAME_IAX) && (f.subclass == AST_IAX_COMMAND_NEW))
1619 pthread_mutex_lock(&iaxs_lock);
1620 fr.callno = find_callno(ntohs(mh->callno) & ~AST_FLAG_FULL, dcallno, &sin, new);
1621 if ((fr.callno < 0) || !iaxs[fr.callno]) {
1622 /* A call arrived for a non-existant destination. Unless it's an "inval"
1623 frame, reply with an inval */
1624 if (ntohs(mh->callno) & AST_FLAG_FULL) {
1625 /* We can only raw hangup control frames */
1626 if ((f.subclass != AST_IAX_COMMAND_INVAL) || (f.frametype != AST_FRAME_IAX))
1627 raw_hangup(&sin, ntohs(fh->dcallno), ntohs(mh->callno));
1629 pthread_mutex_unlock(&iaxs_lock);
1632 iaxs[fr.callno]->peercallno = ntohs(mh->callno) & ~AST_FLAG_FULL;
1633 if (ntohs(mh->callno) & AST_FLAG_FULL) {
1635 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", ntohs(fh->seqno), f.frametype, f.subclass);
1636 /* Check if it's out of order (and not an ACK or INVAL) */
1637 fr.seqno = ntohs(fh->seqno);
1638 if (iaxs[fr.callno]->iseqno != fr.seqno) {
1640 ((f.subclass != AST_IAX_COMMAND_ACK) && (f.subclass != AST_IAX_COMMAND_INVAL)) ||
1641 (f.frametype != AST_FRAME_IAX)) {
1642 /* If it's not an ACK packet, it's out of order. */
1644 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
1645 iaxs[fr.callno]->iseqno, fr.seqno, f.frametype, f.subclass);
1646 if (iaxs[fr.callno]->iseqno > fr.seqno) {
1647 /* If we've already seen it, ack it XXX There's a border condition here XXX */
1648 if ((f.frametype != AST_FRAME_IAX) ||
1649 ((f.subclass != AST_IAX_COMMAND_ACK) && (f.subclass != AST_IAX_COMMAND_INVAL))) {
1651 ast_log(LOG_DEBUG, "Acking anyway\n");
1652 send_command(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.seqno);
1655 pthread_mutex_unlock(&iaxs_lock);
1659 /* Increment unless it's an ACK */
1660 if ((f.subclass != AST_IAX_COMMAND_ACK) ||
1661 (f.frametype != AST_FRAME_IAX))
1662 iaxs[fr.callno]->iseqno++;
1665 if (res < sizeof(struct ast_iax_full_hdr)) {
1666 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, sizeof(struct ast_iax_full_hdr));
1667 pthread_mutex_unlock(&iaxs_lock);
1670 f.datalen = res - sizeof(struct ast_iax_full_hdr);
1672 f.data = buf + sizeof(struct ast_iax_full_hdr);
1675 fr.ts = ntohl(fh->ts);
1676 /* Unless this is an ACK or INVAL frame, ack it */
1677 if ((f.frametype != AST_FRAME_IAX) ||
1678 ((f.subclass != AST_IAX_COMMAND_ACK) && (f.subclass != AST_IAX_COMMAND_INVAL)))
1679 send_command(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.seqno);
1680 if (f.frametype == AST_FRAME_VOICE)
1681 iaxs[fr.callno]->voiceformat = f.subclass;
1682 if (f.frametype == AST_FRAME_IAX) {
1683 /* Handle the IAX pseudo frame itself */
1685 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
1686 switch(f.subclass) {
1687 case AST_IAX_COMMAND_ACK:
1688 /* Ack the packet with the given timestamp */
1689 pthread_mutex_lock(&iaxq.lock);
1690 for (cur = iaxq.head; cur ; cur = cur->next) {
1691 /* If it's our call, and our timestamp, mark -1 retries */
1692 if ((fr.callno == cur->callno) && (fr.seqno == cur->seqno))
1695 pthread_mutex_unlock(&iaxq.lock);
1697 case AST_IAX_COMMAND_NEW:
1698 ((char *)f.data)[f.datalen] = '\0';
1699 if (check_access(fr.callno, &sin, f.data, f.datalen)) {
1700 /* They're not allowed on */
1701 send_command(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_REJECT, 0, "No authority found", strlen("No authority found"), -1);
1702 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s'\n", inet_ntoa(sin.sin_addr), f.data);
1703 /* XXX Not guaranteed to work, but probably does XXX */
1704 pthread_mutex_lock(&iaxq.lock);
1705 send_packet(iaxq.tail);
1706 pthread_mutex_unlock(&iaxq.lock);
1707 iax_destroy(fr.callno);
1710 if (!strlen(iaxs[fr.callno]->secret)) {
1711 /* No authentication required, let them in */
1712 send_command(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_ACCEPT, 0, NULL, 0, -1);
1713 iaxs[fr.callno]->state |= IAX_STATE_STARTED;
1714 if(!(c = ast_iax_new(iaxs[fr.callno], AST_STATE_RING)))
1715 iax_destroy(fr.callno);
1717 c->format = iaxs[fr.callno]->peerformats;
1720 authenticate_request(iaxs[fr.callno]);
1721 iaxs[fr.callno]->state |= IAX_STATE_AUTHENTICATED;
1723 case AST_IAX_COMMAND_HANGUP:
1725 iaxs[fr.callno]->error = ENOTCONN;
1727 iax_destroy(fr.callno);
1729 case AST_IAX_COMMAND_REJECT:
1731 ((char *)f.data)[f.datalen] = '\0';
1732 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", inet_ntoa(iaxs[fr.callno]->addr.sin_addr), f.data);
1733 iaxs[fr.callno]->error = EPERM;
1734 iax_destroy(fr.callno);
1736 case AST_IAX_COMMAND_ACCEPT:
1738 ((char *)f.data)[f.datalen]='\0';
1739 iax_getformats(fr.callno, (char *)f.data);
1741 iaxs[fr.callno]->peerformats = iax_capability;
1743 if (option_verbose > 2)
1744 ast_verbose(VERBOSE_PREFIX_3 "Call accepted by %s\n", inet_ntoa(iaxs[fr.callno]->addr.sin_addr));
1745 iaxs[fr.callno]->state |= IAX_STATE_STARTED;
1746 if (iaxs[fr.callno]->owner) {
1747 /* Switch us to use a compatible format */
1748 iaxs[fr.callno]->owner->format &= iaxs[fr.callno]->peerformats;
1750 if (!iaxs[fr.callno]->owner->format)
1751 iaxs[fr.callno]->owner->format = iaxs[fr.callno]->peerformats & iax_capability;
1752 if (!iaxs[fr.callno]->owner->format) {
1753 ast_log(LOG_WARNING, "Unable to negotiate a common format with the peer.");
1754 iaxs[fr.callno]->error = EBADE;
1755 iax_destroy(fr.callno);
1757 if (option_verbose > 2)
1758 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %d\n", iaxs[fr.callno]->owner->format);
1763 case AST_IAX_COMMAND_PING:
1764 /* Send back a pong packet with the original timestamp */
1765 send_command(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_PONG, fr.ts, NULL, 0, -1);
1767 case AST_IAX_COMMAND_PONG:
1768 iaxs[fr.callno]->pingtime = calc_timestamp(iaxs[fr.callno], 0) - fr.ts;
1770 case AST_IAX_COMMAND_LAGRQ:
1771 case AST_IAX_COMMAND_LAGRP:
1772 /* A little strange -- We have to actually go through the motions of
1773 delivering the packet. In the very last step, it will be properly
1774 handled by do_deliver */
1775 snprintf(src, sizeof(src), "LAGRQ-IAX/%s/%d", inet_ntoa(sin.sin_addr),fr.callno);
1781 schedule_delivery(iaxfrdup2(&fr, 0));
1783 case AST_IAX_COMMAND_AUTHREQ:
1784 ((char *)f.data)[f.datalen] = '\0';
1785 if (authenticate_reply(iaxs[fr.callno], &iaxs[fr.callno]->addr, (char *)f.data)) {
1786 ast_log(LOG_WARNING,
1787 "I don't know how to authenticate %s to %s\n",
1788 f.data, inet_ntoa(iaxs[fr.callno]->addr.sin_addr));
1789 iax_destroy(fr.callno);
1792 case AST_IAX_COMMAND_AUTHREP:
1793 ((char *)f.data)[f.datalen] = '\0';
1794 if (authenticate_verify(iaxs[fr.callno], (char *)f.data)) {
1795 ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", inet_ntoa(iaxs[fr.callno]->addr.sin_addr), iaxs[fr.callno]->username);
1796 send_command(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_REJECT, 0, "No authority found", strlen("No authority found"), -1);
1797 /* XXX Not guaranteed to work, but probably does XXX */
1798 pthread_mutex_lock(&iaxq.lock);
1799 send_packet(iaxq.tail);
1800 pthread_mutex_unlock(&iaxq.lock);
1801 iax_destroy(fr.callno);
1804 /* Authentication is fine, go ahead */
1805 send_command(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_ACCEPT, 0, NULL, 0, -1);
1806 iaxs[fr.callno]->state |= IAX_STATE_STARTED;
1807 if(!(c = ast_iax_new(iaxs[fr.callno], AST_STATE_RING)))
1808 iax_destroy(fr.callno);
1810 c->format = iaxs[fr.callno]->peerformats;
1812 case AST_IAX_COMMAND_INVAL:
1813 iaxs[fr.callno]->error = ENOTCONN;
1814 iax_destroy(fr.callno);
1816 ast_log(LOG_DEBUG, "Destroying call %d\n", fr.callno);
1819 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr.callno, iaxs[fr.callno]->peercallno);
1821 /* Don't actually pass these frames along */
1822 pthread_mutex_unlock(&iaxs_lock);
1827 f.frametype = AST_FRAME_VOICE;
1828 if (iaxs[fr.callno]->voiceformat > 0)
1829 f.subclass = iaxs[fr.callno]->voiceformat;
1831 ast_log(LOG_WARNING, "Received mini frame before first full voice frame\n ");
1832 pthread_mutex_unlock(&iaxs_lock);
1835 f.datalen = res - sizeof(struct ast_iax_mini_hdr);
1836 if (f.datalen < 0) {
1837 ast_log(LOG_WARNING, "Datalen < 0?\n");
1838 pthread_mutex_unlock(&iaxs_lock);
1842 f.data = buf + sizeof(struct ast_iax_mini_hdr);
1845 fr.ts = (iaxs[fr.callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
1847 /* Don't pass any packets until we're started */
1848 if (!(iaxs[fr.callno]->state & IAX_STATE_STARTED)) {
1849 pthread_mutex_unlock(&iaxs_lock);
1853 snprintf(src, sizeof(src), "IAX/%s/%d", inet_ntoa(sin.sin_addr),fr.callno);
1858 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
1859 f.timelen = get_timelen(&f);
1863 /* If this is our most recent packet, use it as our basis for timestamping */
1864 if (iaxs[fr.callno]->last < fr.ts) {
1865 iaxs[fr.callno]->last = fr.ts;
1868 ast_log(LOG_DEBUG, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass, fr.ts, iaxs[fr.callno]->last);
1871 schedule_delivery(iaxfrdup2(&fr, 0));
1872 /* Always run again */
1873 pthread_mutex_unlock(&iaxs_lock);
1877 static void free_ha(struct iax_ha *ha)
1887 static void free_context(struct iax_context *con)
1889 struct iax_context *conl;
1897 static struct ast_channel *iax_request(char *type, int format, void *data)
1900 struct sockaddr_in sin;
1903 struct ast_channel *c;
1904 strncpy(s, (char *)data, sizeof(s));
1907 st = strtok(NULL, "@");
1910 /* Populate our address from the given */
1911 if (create_addr(&sin, st)) {
1912 ast_log(LOG_WARNING, "Unable to assign address\n");
1915 pthread_mutex_lock(&iaxs_lock);
1916 callno = find_callno(-1, -1, &sin, NEW_FORCE);
1918 ast_log(LOG_WARNING, "Unable to create call\n");
1921 c = ast_iax_new(iaxs[callno], AST_STATE_DOWN);
1923 /* Choose a format we can live with */
1924 if (c->format & format)
1925 c->format &= format;
1927 c->format = ast_translator_best_choice(format, c->format);
1929 pthread_mutex_unlock(&iaxs_lock);
1933 static void *network_thread(void *ignore)
1935 /* Our job is simple: Send queued messages, retrying if necessary. Read frames
1936 from the network, and queue them for delivery to the channels */
1938 struct ast_iax_frame *f, *freeme;
1939 /* Establish I/O callback for socket read */
1940 ast_io_add(io, netsocket, socket_read, AST_IO_IN, NULL);
1941 pthread_mutex_lock(&iaxs_lock);
1943 /* Go through the queue, sending messages which have not yet been
1944 sent, and scheduling retransmissions if appropriate */
1945 pthread_mutex_lock(&iaxq.lock);
1951 /* Send a copy immediately */
1952 if (iaxs[f->callno]) {
1955 if (f->retries < 0) {
1956 /* This is not supposed to be retransmitted */
1958 f->prev->next = f->next;
1960 iaxq.head = f->next;
1962 f->next->prev = f->prev;
1964 iaxq.tail = f->prev;
1966 /* Free the frame */
1968 /* Free the iax frame */
1971 /* We need reliable delivery. Schedule a retransmission */
1973 ast_sched_add(sched, f->retrytime, attempt_transmit, f);
1980 pthread_mutex_unlock(&iaxq.lock);
1981 pthread_mutex_unlock(&iaxs_lock);
1982 res = ast_sched_wait(sched);
1983 res = ast_io_wait(io, res);
1984 pthread_mutex_lock(&iaxs_lock);
1986 ast_sched_runq(sched);
1991 static int start_network_thread()
1993 return pthread_create(&netthreadid, NULL, network_thread, NULL);
1996 static struct iax_context *build_context(char *context)
1998 struct iax_context *con = malloc(sizeof(struct iax_context));
2000 strncpy(con->context, context, sizeof(con->context));
2006 static struct iax_ha *build_ha(char *sense, char *stuff)
2008 struct iax_ha *ha = malloc(sizeof(struct iax_ha));
2012 nm = strtok(NULL, "/");
2014 nm = "255.255.255.255";
2015 if (!inet_aton(stuff, &ha->netaddr)) {
2016 ast_log(LOG_WARNING, "%s not a valid IP\n", stuff);
2020 if (!inet_aton(nm, &ha->netmask)) {
2021 ast_log(LOG_WARNING, "%s not a valid netmask\n", nm);
2025 ha->netaddr.s_addr &= ha->netmask.s_addr;
2026 if (!strcasecmp(sense, "a")) {
2027 ha->sense = IAX_SENSE_ALLOW;
2029 ha->sense = IAX_SENSE_DENY;
2036 static struct iax_peer *build_peer(char *name, struct ast_variable *v)
2038 struct iax_peer *peer;
2041 peer = malloc(sizeof(struct iax_peer));
2043 memset(peer, 0, sizeof(struct iax_peer));
2044 strncpy(peer->name, name, sizeof(peer->name));
2045 peer->addr.sin_port = htons(AST_DEFAULT_IAX_PORTNO);
2047 if (!strcasecmp(v->name, "secret"))
2048 strncpy(peer->secret, v->value, sizeof(peer->secret));
2049 else if (!strcasecmp(v->name, "host")) {
2050 if (!strcasecmp(v->value, "dynamic")) {
2051 /* They'll register with us */
2053 memset(&peer->addr.sin_addr, 0, 4);
2056 hp = gethostbyname(v->value);
2058 memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr));
2060 ast_log(LOG_WARNING, "Unable to lookup '%s'\n", v->value);
2065 inet_aton("255.255.255.255", &peer->mask);
2068 else if (!strcasecmp(v->name, "mask")) {
2070 inet_aton(v->value, &peer->mask);
2071 } else if (!strcasecmp(v->name, "port"))
2072 peer->addr.sin_port = htons(atoi(v->value));
2073 else if (!strcasecmp(v->name, "username"))
2074 strncpy(peer->username, v->value, sizeof(peer->username));
2081 static struct iax_user *build_user(char *name, struct ast_variable *v)
2083 struct iax_user *user;
2084 struct iax_context *con, *conl = NULL;
2085 struct iax_ha *ha, *hal = NULL;
2086 user = (struct iax_user *)malloc(sizeof(struct iax_user));
2088 memset(user, 0, sizeof(struct iax_user));
2089 strncpy(user->name, name, sizeof(user->name));
2091 if (!strcasecmp(v->name, "context")) {
2092 con = build_context(v->value);
2097 user->contexts = con;
2100 } else if (!strcasecmp(v->name, "allow") ||
2101 !strcasecmp(v->name, "deny")) {
2102 ha = build_ha(v->name, v->value);
2110 } else if (!strcasecmp(v->name, "auth")) {
2111 strncpy(user->methods, v->value, sizeof(user->methods));
2112 } else if (!strcasecmp(v->name, "secret")) {
2113 strncpy(user->secret, v->value, sizeof(user->secret));
2124 struct ast_config *cfg;
2125 struct ast_variable *v;
2126 struct iax_user *user;
2127 struct iax_peer *peer;
2132 struct sockaddr_in sin;
2134 sin.sin_family = AF_INET;
2135 sin.sin_port = ntohs(AST_DEFAULT_IAX_PORTNO);
2136 sin.sin_addr.s_addr = INADDR_ANY;
2138 io = io_context_create();
2139 sched = sched_context_create();
2141 if (!io || !sched) {
2142 ast_log(LOG_ERROR, "Out of memory\n");
2146 pthread_mutex_init(&iaxq.lock, NULL);
2147 pthread_mutex_init(&userl.lock, NULL);
2149 ast_cli_register(&cli_show_users);
2150 ast_cli_register(&cli_show_channels);
2151 ast_cli_register(&cli_show_peers);
2152 ast_cli_register(&cli_set_jitter);
2153 #ifdef IAX_SIMULATOR
2154 ast_cli_register(&delay_cli);
2155 ast_cli_register(&deviation_cli);
2156 ast_cli_register(&reliability_cli);
2157 ast_cli_register(&sim_show_cli);
2159 cfg = ast_load(config);
2162 ast_log(LOG_ERROR, "Unable to load config %s\n", config);
2165 v = ast_variable_browse(cfg, "general");
2167 if (!strcasecmp(v->name, "port"))
2168 sin.sin_port = ntohs(atoi(v->value));
2169 else if (!strcasecmp(v->name, "pingtime"))
2170 ping_time = atoi(v->value);
2171 else if (!strcasecmp(v->name, "maxjitterbuffer"))
2172 maxjitterbuffer = atoi(v->value);
2173 else if (!strcasecmp(v->name, "maxexcessbuffer"))
2174 max_jitter_buffer = atoi(v->value);
2175 else if (!strcasecmp(v->name, "lagrqtime"))
2176 lagrq_time = atoi(v->value);
2177 else if (!strcasecmp(v->name, "dropcount"))
2178 iax_dropcount = atoi(v->value);
2179 else if (!strcasecmp(v->name, "bindaddr"))
2180 inet_aton(v->value, &sin.sin_addr);
2181 else if (!strcasecmp(v->name, "jitterbuffer"))
2182 use_jitterbuffer = ast_true(v->value);
2183 else if (!strcasecmp(v->name, "bandwidth")) {
2184 if (!strcasecmp(v->value, "low")) {
2185 iax_capability = IAX_CAPABILITY_LOWBANDWIDTH;
2186 } else if (!strcasecmp(v->value, "medium")) {
2187 iax_capability = IAX_CAPABILITY_MEDBANDWIDTH;
2188 } else if (!strcasecmp(v->value, "high")) {
2189 iax_capability = IAX_CAPABILITY_FULLBANDWIDTH;
2191 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
2192 } else if (!strcasecmp(v->name, "allow")) {
2193 format = ast_getformatbyname(v->value);
2195 ast_log(LOG_WARNING, "Cannot allow unknown format '%s'\n", v->value);
2197 iax_capability |= format;
2198 } else if (!strcasecmp(v->name, "disallow")) {
2199 format = ast_getformatbyname(v->value);
2201 ast_log(LOG_WARNING, "Cannot disallow unknown format '%s'\n", v->value);
2203 iax_capability &= ~format;
2207 cat = ast_category_browse(cfg, NULL);
2209 if (strcasecmp(cat, "general")) {
2210 utype = ast_variable_retrieve(cfg, cat, "type");
2212 if (!strcasecmp(utype, "user")) {
2213 user = build_user(cat, ast_variable_browse(cfg, cat));
2215 pthread_mutex_lock(&userl.lock);
2216 user->next = userl.users;
2218 pthread_mutex_unlock(&userl.lock);
2220 } else if (!strcasecmp(utype, "peer")) {
2221 peer = build_peer(cat, ast_variable_browse(cfg, cat));
2223 pthread_mutex_lock(&peerl.lock);
2224 peer->next = peerl.peers;
2226 pthread_mutex_unlock(&peerl.lock);
2229 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config);
2232 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
2234 cat = ast_category_browse(cfg, cat);
2237 if (ast_channel_register(type, tdesc, iax_capability, iax_request)) {
2238 ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
2243 /* Make a UDP socket */
2244 netsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
2246 if (netsocket < 0) {
2247 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
2250 if (bind(netsocket, &sin, sizeof(sin))) {
2251 ast_log(LOG_ERROR, "Unable to bind to %s port %d\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
2256 res = start_network_thread();
2257 if (option_verbose > 1)
2258 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening on %s port %d\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
2260 ast_log(LOG_ERROR, "Unable to start network thread\n");
2273 struct iax_user *user, *userlast;
2274 struct iax_peer *peer, *peerlast;
2276 /* Cancel the network thread, close the net socket */
2277 pthread_cancel(netthreadid);
2278 pthread_join(netthreadid, NULL);
2280 for (x=0;x<AST_IAX_MAX_CALLS;x++)
2283 ast_cli_unregister(&cli_show_users);
2284 ast_cli_unregister(&cli_show_channels);
2285 ast_cli_unregister(&cli_show_peers);
2286 ast_cli_unregister(&cli_set_jitter);
2287 #ifdef IAX_SIMULATOR
2288 ast_cli_unregister(&delay_cli);
2289 ast_cli_unregister(&deviation_cli);
2290 ast_cli_unregister(&reliability_cli);
2291 ast_cli_unregister(&sim_show_cli);
2293 for (user=userl.users;user;) {
2295 free_context(user->contexts);
2300 for (peer=peerl.peers;peer;) {
2311 pthread_mutex_lock(&usecnt_lock);
2313 pthread_mutex_unlock(&usecnt_lock);