00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include "asterisk.h"
00050
00051 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
00052
00053 #include <stdio.h>
00054 #include <stdlib.h>
00055 #include <string.h>
00056 #include <sys/time.h>
00057 #include <signal.h>
00058 #include <errno.h>
00059 #include <unistd.h>
00060 #include <netinet/in.h>
00061 #include <sys/time.h>
00062 #include <sys/socket.h>
00063 #include <arpa/inet.h>
00064 #include <fcntl.h>
00065
00066 #include "asterisk/udptl.h"
00067 #include "asterisk/frame.h"
00068 #include "asterisk/logger.h"
00069 #include "asterisk/options.h"
00070 #include "asterisk/channel.h"
00071 #include "asterisk/acl.h"
00072 #include "asterisk/channel.h"
00073 #include "asterisk/config.h"
00074 #include "asterisk/lock.h"
00075 #include "asterisk/utils.h"
00076 #include "asterisk/cli.h"
00077 #include "asterisk/unaligned.h"
00078 #include "asterisk/utils.h"
00079
00080 #define UDPTL_MTU 1200
00081
00082 #if !defined(FALSE)
00083 #define FALSE 0
00084 #endif
00085 #if !defined(TRUE)
00086 #define TRUE (!FALSE)
00087 #endif
00088
00089 static int udptlstart;
00090 static int udptlend;
00091 static int udptldebug;
00092 static struct sockaddr_in udptldebugaddr;
00093 #ifdef SO_NO_CHECK
00094 static int nochecksums;
00095 #endif
00096 static int udptlfectype;
00097 static int udptlfecentries;
00098 static int udptlfecspan;
00099 static int udptlmaxdatagram;
00100
00101 #define LOCAL_FAX_MAX_DATAGRAM 400
00102 #define MAX_FEC_ENTRIES 5
00103 #define MAX_FEC_SPAN 5
00104
00105 #define UDPTL_BUF_MASK 15
00106
00107 typedef struct {
00108 int buf_len;
00109 uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
00110 } udptl_fec_tx_buffer_t;
00111
00112 typedef struct {
00113 int buf_len;
00114 uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
00115 int fec_len[MAX_FEC_ENTRIES];
00116 uint8_t fec[MAX_FEC_ENTRIES][LOCAL_FAX_MAX_DATAGRAM];
00117 int fec_span;
00118 int fec_entries;
00119 } udptl_fec_rx_buffer_t;
00120
00121
00122 struct ast_udptl {
00123 int fd;
00124 char resp;
00125 struct ast_frame f[16];
00126 unsigned char rawdata[8192 + AST_FRIENDLY_OFFSET];
00127 unsigned int lasteventseqn;
00128 int nat;
00129 int flags;
00130 struct sockaddr_in us;
00131 struct sockaddr_in them;
00132 int *ioid;
00133 struct sched_context *sched;
00134 struct io_context *io;
00135 void *data;
00136 ast_udptl_callback callback;
00137 int udptl_offered_from_local;
00138
00139
00140
00141 int error_correction_scheme;
00142
00143
00144
00145 int error_correction_entries;
00146
00147
00148
00149 int error_correction_span;
00150
00151
00152
00153 int far_max_datagram_size;
00154
00155
00156
00157 int local_max_datagram_size;
00158
00159 int verbose;
00160
00161 struct sockaddr_in far;
00162
00163 int tx_seq_no;
00164 int rx_seq_no;
00165 int rx_expected_seq_no;
00166
00167 udptl_fec_tx_buffer_t tx[UDPTL_BUF_MASK + 1];
00168 udptl_fec_rx_buffer_t rx[UDPTL_BUF_MASK + 1];
00169 };
00170
00171 static struct ast_udptl_protocol *protos;
00172
00173 static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, int len);
00174 static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, uint8_t *ifp, int ifp_len);
00175
00176 static inline int udptl_debug_test_addr(struct sockaddr_in *addr)
00177 {
00178 if (udptldebug == 0)
00179 return 0;
00180 if (udptldebugaddr.sin_addr.s_addr) {
00181 if (((ntohs(udptldebugaddr.sin_port) != 0)
00182 && (udptldebugaddr.sin_port != addr->sin_port))
00183 || (udptldebugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
00184 return 0;
00185 }
00186 return 1;
00187 }
00188
00189 static int decode_length(uint8_t *buf, int limit, int *len, int *pvalue)
00190 {
00191 if ((buf[*len] & 0x80) == 0) {
00192 if (*len >= limit)
00193 return -1;
00194 *pvalue = buf[*len];
00195 (*len)++;
00196 return 0;
00197 }
00198 if ((buf[*len] & 0x40) == 0) {
00199 if (*len >= limit - 1)
00200 return -1;
00201 *pvalue = (buf[*len] & 0x3F) << 8;
00202 (*len)++;
00203 *pvalue |= buf[*len];
00204 (*len)++;
00205 return 0;
00206 }
00207 if (*len >= limit)
00208 return -1;
00209 *pvalue = (buf[*len] & 0x3F) << 14;
00210 (*len)++;
00211
00212 return 1;
00213 }
00214
00215
00216 static int decode_open_type(uint8_t *buf, int limit, int *len, const uint8_t **p_object, int *p_num_octets)
00217 {
00218 int octet_cnt;
00219 int octet_idx;
00220 int stat;
00221 int i;
00222 const uint8_t **pbuf;
00223
00224 for (octet_idx = 0, *p_num_octets = 0; ; octet_idx += octet_cnt) {
00225 if ((stat = decode_length(buf, limit, len, &octet_cnt)) < 0)
00226 return -1;
00227 if (octet_cnt > 0) {
00228 *p_num_octets += octet_cnt;
00229
00230 pbuf = &p_object[octet_idx];
00231 i = 0;
00232
00233 if ((*len + octet_cnt) > limit)
00234 return -1;
00235
00236 *pbuf = &buf[*len];
00237 *len += octet_cnt;
00238 }
00239 if (stat == 0)
00240 break;
00241 }
00242 return 0;
00243 }
00244
00245
00246 static int encode_length(uint8_t *buf, int *len, int value)
00247 {
00248 int multiplier;
00249
00250 if (value < 0x80) {
00251
00252 buf[*len] = value;
00253 (*len)++;
00254 return value;
00255 }
00256 if (value < 0x4000) {
00257
00258
00259 buf[*len] = ((0x8000 | value) >> 8) & 0xFF;
00260 (*len)++;
00261 buf[*len] = value & 0xFF;
00262 (*len)++;
00263 return value;
00264 }
00265
00266 multiplier = (value < 0x10000) ? (value >> 14) : 4;
00267
00268 buf[*len] = 0xC0 | multiplier;
00269 (*len)++;
00270 return multiplier << 14;
00271 }
00272
00273
00274 static int encode_open_type(uint8_t *buf, int *len, const uint8_t *data, int num_octets)
00275 {
00276 int enclen;
00277 int octet_idx;
00278 uint8_t zero_byte;
00279
00280
00281 if (num_octets == 0) {
00282 zero_byte = 0;
00283 data = &zero_byte;
00284 num_octets = 1;
00285 }
00286
00287 for (octet_idx = 0; ; num_octets -= enclen, octet_idx += enclen) {
00288 if ((enclen = encode_length(buf, len, num_octets)) < 0)
00289 return -1;
00290 if (enclen > 0) {
00291 memcpy(&buf[*len], &data[octet_idx], enclen);
00292 *len += enclen;
00293 }
00294 if (enclen >= num_octets)
00295 break;
00296 }
00297
00298 return 0;
00299 }
00300
00301
00302 static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, int len)
00303 {
00304 int stat;
00305 int stat2;
00306 int i;
00307 int j;
00308 int k;
00309 int l;
00310 int m;
00311 int x;
00312 int limit;
00313 int which;
00314 int ptr;
00315 int count;
00316 int total_count;
00317 int seq_no;
00318 const uint8_t *ifp;
00319 const uint8_t *data;
00320 int ifp_len;
00321 int repaired[16];
00322 const uint8_t *bufs[16];
00323 int lengths[16];
00324 int span;
00325 int entries;
00326 int ifp_no;
00327
00328 ptr = 0;
00329 ifp_no = 0;
00330 memset(&s->f[0], 0, sizeof(s->f[0]));
00331
00332
00333 if (ptr + 2 > len)
00334 return -1;
00335 seq_no = (buf[0] << 8) | buf[1];
00336 ptr += 2;
00337
00338
00339 if ((stat = decode_open_type(buf, len, &ptr, &ifp, &ifp_len)) != 0)
00340 return -1;
00341
00342 if (ptr + 1 > len)
00343 return -1;
00344 if ((buf[ptr++] & 0x80) == 0) {
00345
00346 if (seq_no > s->rx_seq_no) {
00347
00348
00349 total_count = 0;
00350 do {
00351 if ((stat2 = decode_length(buf, len, &ptr, &count)) < 0)
00352 return -1;
00353 for (i = 0; i < count; i++) {
00354 if ((stat = decode_open_type(buf, len, &ptr, &bufs[total_count + i], &lengths[total_count + i])) != 0)
00355 return -1;
00356 }
00357 total_count += count;
00358 }
00359 while (stat2 > 0);
00360
00361 for (i = total_count; i > 0; i--) {
00362 if (seq_no - i >= s->rx_seq_no) {
00363
00364
00365
00366 s->f[ifp_no].frametype = AST_FRAME_MODEM;
00367 s->f[ifp_no].subclass = AST_MODEM_T38;
00368
00369 s->f[ifp_no].mallocd = 0;
00370 s->f[ifp_no].seqno = seq_no - i;
00371 s->f[ifp_no].datalen = lengths[i - 1];
00372 s->f[ifp_no].data = (uint8_t *) bufs[i - 1];
00373 s->f[ifp_no].offset = 0;
00374 s->f[ifp_no].src = "UDPTL";
00375 if (ifp_no > 0)
00376 AST_LIST_NEXT(&s->f[ifp_no - 1], frame_list) = &s->f[ifp_no];
00377 AST_LIST_NEXT(&s->f[ifp_no], frame_list) = NULL;
00378 ifp_no++;
00379 }
00380 }
00381 }
00382 }
00383 else
00384 {
00385
00386
00387 if (ifp_len > LOCAL_FAX_MAX_DATAGRAM)
00388 return -1;
00389
00390 for ( ; seq_no > s->rx_seq_no; s->rx_seq_no++) {
00391 x = s->rx_seq_no & UDPTL_BUF_MASK;
00392 s->rx[x].buf_len = -1;
00393 s->rx[x].fec_len[0] = 0;
00394 s->rx[x].fec_span = 0;
00395 s->rx[x].fec_entries = 0;
00396 }
00397
00398 x = seq_no & UDPTL_BUF_MASK;
00399
00400 memset(repaired, 0, sizeof(repaired));
00401
00402
00403 memcpy(s->rx[x].buf, ifp, ifp_len);
00404 s->rx[x].buf_len = ifp_len;
00405 repaired[x] = TRUE;
00406
00407
00408
00409
00410 if (ptr + 2 > len)
00411 return -1;
00412 if (buf[ptr++] != 1)
00413 return -1;
00414 span = buf[ptr++];
00415 s->rx[x].fec_span = span;
00416
00417
00418
00419 if (ptr + 1 > len)
00420 return -1;
00421 entries = buf[ptr++];
00422 s->rx[x].fec_entries = entries;
00423
00424
00425 for (i = 0; i < entries; i++) {
00426 if ((stat = decode_open_type(buf, len, &ptr, &data, &s->rx[x].fec_len[i])) != 0)
00427 return -1;
00428 if (s->rx[x].fec_len[i] > LOCAL_FAX_MAX_DATAGRAM)
00429 return -1;
00430
00431
00432 memcpy(s->rx[x].fec[i], data, s->rx[x].fec_len[i]);
00433 #if 0
00434 fprintf(stderr, "FEC: ");
00435 for (j = 0; j < s->rx[x].fec_len[i]; j++)
00436 fprintf(stderr, "%02X ", data[j]);
00437 fprintf(stderr, "\n");
00438 #endif
00439 }
00440
00441
00442
00443 for (l = x; l != ((x - (16 - span*entries)) & UDPTL_BUF_MASK); l = (l - 1) & UDPTL_BUF_MASK) {
00444 if (s->rx[l].fec_len[0] <= 0)
00445 continue;
00446 for (m = 0; m < s->rx[l].fec_entries; m++) {
00447 limit = (l + m) & UDPTL_BUF_MASK;
00448 for (which = -1, k = (limit - s->rx[l].fec_span * s->rx[l].fec_entries) & UDPTL_BUF_MASK; k != limit; k = (k + s->rx[l].fec_entries) & UDPTL_BUF_MASK) {
00449 if (s->rx[k].buf_len <= 0)
00450 which = (which == -1) ? k : -2;
00451 }
00452 if (which >= 0) {
00453
00454 for (j = 0; j < s->rx[l].fec_len[m]; j++) {
00455 s->rx[which].buf[j] = s->rx[l].fec[m][j];
00456 for (k = (limit - s->rx[l].fec_span * s->rx[l].fec_entries) & UDPTL_BUF_MASK; k != limit; k = (k + s->rx[l].fec_entries) & UDPTL_BUF_MASK)
00457 s->rx[which].buf[j] ^= (s->rx[k].buf_len > j) ? s->rx[k].buf[j] : 0;
00458 }
00459 s->rx[which].buf_len = s->rx[l].fec_len[m];
00460 repaired[which] = TRUE;
00461 }
00462 }
00463 }
00464
00465 for (l = (x + 1) & UDPTL_BUF_MASK, j = seq_no - UDPTL_BUF_MASK; l != x; l = (l + 1) & UDPTL_BUF_MASK, j++) {
00466 if (repaired[l]) {
00467
00468 s->f[ifp_no].frametype = AST_FRAME_MODEM;
00469 s->f[ifp_no].subclass = AST_MODEM_T38;
00470
00471 s->f[ifp_no].mallocd = 0;
00472 s->f[ifp_no].seqno = j;
00473 s->f[ifp_no].datalen = s->rx[l].buf_len;
00474 s->f[ifp_no].data = s->rx[l].buf;
00475 s->f[ifp_no].offset = 0;
00476 s->f[ifp_no].src = "UDPTL";
00477 if (ifp_no > 0)
00478 AST_LIST_NEXT(&s->f[ifp_no - 1], frame_list) = &s->f[ifp_no];
00479 AST_LIST_NEXT(&s->f[ifp_no], frame_list) = NULL;
00480 ifp_no++;
00481 }
00482 }
00483 }
00484
00485
00486
00487 if (seq_no >= s->rx_seq_no) {
00488
00489 s->f[ifp_no].frametype = AST_FRAME_MODEM;
00490 s->f[ifp_no].subclass = AST_MODEM_T38;
00491
00492 s->f[ifp_no].mallocd = 0;
00493 s->f[ifp_no].seqno = seq_no;
00494 s->f[ifp_no].datalen = ifp_len;
00495 s->f[ifp_no].data = (uint8_t *) ifp;
00496 s->f[ifp_no].offset = 0;
00497 s->f[ifp_no].src = "UDPTL";
00498 if (ifp_no > 0)
00499 AST_LIST_NEXT(&s->f[ifp_no - 1], frame_list) = &s->f[ifp_no];
00500 AST_LIST_NEXT(&s->f[ifp_no], frame_list) = NULL;
00501
00502 ifp_no++;
00503 }
00504
00505 s->rx_seq_no = seq_no + 1;
00506 return ifp_no;
00507 }
00508
00509
00510 static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, uint8_t *ifp, int ifp_len)
00511 {
00512 uint8_t fec[LOCAL_FAX_MAX_DATAGRAM];
00513 int i;
00514 int j;
00515 int seq;
00516 int entry;
00517 int entries;
00518 int span;
00519 int m;
00520 int len;
00521 int limit;
00522 int high_tide;
00523
00524 seq = s->tx_seq_no & 0xFFFF;
00525
00526
00527 entry = seq & UDPTL_BUF_MASK;
00528
00529
00530
00531 s->tx[entry].buf_len = ifp_len;
00532 memcpy(s->tx[entry].buf, ifp, ifp_len);
00533
00534
00535
00536 len = 0;
00537
00538 buf[len++] = (seq >> 8) & 0xFF;
00539 buf[len++] = seq & 0xFF;
00540
00541
00542 if (encode_open_type(buf, &len, ifp, ifp_len) < 0)
00543 return -1;
00544
00545
00546 switch (s->error_correction_scheme)
00547 {
00548 case UDPTL_ERROR_CORRECTION_NONE:
00549
00550 buf[len++] = 0x00;
00551
00552
00553 if (encode_length(buf, &len, 0) < 0)
00554 return -1;
00555 break;
00556 case UDPTL_ERROR_CORRECTION_REDUNDANCY:
00557
00558 buf[len++] = 0x00;
00559 if (s->tx_seq_no > s->error_correction_entries)
00560 entries = s->error_correction_entries;
00561 else
00562 entries = s->tx_seq_no;
00563
00564
00565 if (encode_length(buf, &len, entries) < 0)
00566 return -1;
00567
00568 for (i = 0; i < entries; i++) {
00569 j = (entry - i - 1) & UDPTL_BUF_MASK;
00570 if (encode_open_type(buf, &len, s->tx[j].buf, s->tx[j].buf_len) < 0)
00571 return -1;
00572 }
00573 break;
00574 case UDPTL_ERROR_CORRECTION_FEC:
00575 span = s->error_correction_span;
00576 entries = s->error_correction_entries;
00577 if (seq < s->error_correction_span*s->error_correction_entries) {
00578
00579 entries = seq/s->error_correction_span;
00580 if (seq < s->error_correction_span)
00581 span = 0;
00582 }
00583
00584 buf[len++] = 0x80;
00585
00586
00587 buf[len++] = 1;
00588 buf[len++] = span;
00589
00590
00591 buf[len++] = entries;
00592 for (m = 0; m < entries; m++) {
00593
00594 limit = (entry + m) & UDPTL_BUF_MASK;
00595 high_tide = 0;
00596 for (i = (limit - span*entries) & UDPTL_BUF_MASK; i != limit; i = (i + entries) & UDPTL_BUF_MASK) {
00597 if (high_tide < s->tx[i].buf_len) {
00598 for (j = 0; j < high_tide; j++)
00599 fec[j] ^= s->tx[i].buf[j];
00600 for ( ; j < s->tx[i].buf_len; j++)
00601 fec[j] = s->tx[i].buf[j];
00602 high_tide = s->tx[i].buf_len;
00603 } else {
00604 for (j = 0; j < s->tx[i].buf_len; j++)
00605 fec[j] ^= s->tx[i].buf[j];
00606 }
00607 }
00608 if (encode_open_type(buf, &len, fec, high_tide) < 0)
00609 return -1;
00610 }
00611 break;
00612 }
00613
00614 if (s->verbose)
00615 fprintf(stderr, "\n");
00616
00617 s->tx_seq_no++;
00618 return len;
00619 }
00620
00621 int ast_udptl_fd(struct ast_udptl *udptl)
00622 {
00623 return udptl->fd;
00624 }
00625
00626 void ast_udptl_set_data(struct ast_udptl *udptl, void *data)
00627 {
00628 udptl->data = data;
00629 }
00630
00631 void ast_udptl_set_callback(struct ast_udptl *udptl, ast_udptl_callback callback)
00632 {
00633 udptl->callback = callback;
00634 }
00635
00636 void ast_udptl_setnat(struct ast_udptl *udptl, int nat)
00637 {
00638 udptl->nat = nat;
00639 }
00640
00641 static int udptlread(int *id, int fd, short events, void *cbdata)
00642 {
00643 struct ast_udptl *udptl = cbdata;
00644 struct ast_frame *f;
00645
00646 if ((f = ast_udptl_read(udptl))) {
00647 if (udptl->callback)
00648 udptl->callback(udptl, f, udptl->data);
00649 }
00650 return 1;
00651 }
00652
00653 struct ast_frame *ast_udptl_read(struct ast_udptl *udptl)
00654 {
00655 int res;
00656 struct sockaddr_in sin;
00657 socklen_t len;
00658 uint16_t seqno = 0;
00659 uint16_t *udptlheader;
00660
00661 len = sizeof(sin);
00662
00663
00664 res = recvfrom(udptl->fd,
00665 udptl->rawdata + AST_FRIENDLY_OFFSET,
00666 sizeof(udptl->rawdata) - AST_FRIENDLY_OFFSET,
00667 0,
00668 (struct sockaddr *) &sin,
00669 &len);
00670 udptlheader = (uint16_t *)(udptl->rawdata + AST_FRIENDLY_OFFSET);
00671 if (res < 0) {
00672 if (errno != EAGAIN)
00673 ast_log(LOG_WARNING, "UDPTL read error: %s\n", strerror(errno));
00674 if (errno == EBADF)
00675 CRASH;
00676 return &ast_null_frame;
00677 }
00678
00679
00680 if (!udptl->them.sin_addr.s_addr || !udptl->them.sin_port)
00681 return &ast_null_frame;
00682
00683 if (udptl->nat) {
00684
00685 if ((udptl->them.sin_addr.s_addr != sin.sin_addr.s_addr) ||
00686 (udptl->them.sin_port != sin.sin_port)) {
00687 memcpy(&udptl->them, &sin, sizeof(udptl->them));
00688 ast_log(LOG_DEBUG, "UDPTL NAT: Using address %s:%d\n", ast_inet_ntoa(udptl->them.sin_addr), ntohs(udptl->them.sin_port));
00689 }
00690 }
00691
00692 if (udptl_debug_test_addr(&sin)) {
00693 ast_verbose("Got UDPTL packet from %s:%d (type %d, seq %d, len %d)\n",
00694 ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), 0, seqno, res);
00695 }
00696 #if 0
00697 printf("Got UDPTL packet from %s:%d (seq %d, len = %d)\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), seqno, res);
00698 #endif
00699 if (udptl_rx_packet(udptl, udptl->rawdata + AST_FRIENDLY_OFFSET, res) < 1)
00700 return &ast_null_frame;
00701
00702 return &udptl->f[0];
00703 }
00704
00705 void ast_udptl_offered_from_local(struct ast_udptl* udptl, int local)
00706 {
00707 if (udptl)
00708 udptl->udptl_offered_from_local = local;
00709 else
00710 ast_log(LOG_WARNING, "udptl structure is null\n");
00711 }
00712
00713 int ast_udptl_get_error_correction_scheme(struct ast_udptl* udptl)
00714 {
00715 if (udptl)
00716 return udptl->error_correction_scheme;
00717 else {
00718 ast_log(LOG_WARNING, "udptl structure is null\n");
00719 return -1;
00720 }
00721 }
00722
00723 void ast_udptl_set_error_correction_scheme(struct ast_udptl* udptl, int ec)
00724 {
00725 if (udptl) {
00726 switch (ec) {
00727 case UDPTL_ERROR_CORRECTION_FEC:
00728 udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_FEC;
00729 break;
00730 case UDPTL_ERROR_CORRECTION_REDUNDANCY:
00731 udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_REDUNDANCY;
00732 break;
00733 case UDPTL_ERROR_CORRECTION_NONE:
00734 udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_NONE;
00735 break;
00736 default:
00737 ast_log(LOG_WARNING, "error correction parameter invalid\n");
00738 };
00739 } else
00740 ast_log(LOG_WARNING, "udptl structure is null\n");
00741 }
00742
00743 int ast_udptl_get_local_max_datagram(struct ast_udptl* udptl)
00744 {
00745 if (udptl)
00746 return udptl->local_max_datagram_size;
00747 else {
00748 ast_log(LOG_WARNING, "udptl structure is null\n");
00749 return -1;
00750 }
00751 }
00752
00753 int ast_udptl_get_far_max_datagram(struct ast_udptl* udptl)
00754 {
00755 if (udptl)
00756 return udptl->far_max_datagram_size;
00757 else {
00758 ast_log(LOG_WARNING, "udptl structure is null\n");
00759 return -1;
00760 }
00761 }
00762
00763 void ast_udptl_set_local_max_datagram(struct ast_udptl* udptl, int max_datagram)
00764 {
00765 if (udptl)
00766 udptl->local_max_datagram_size = max_datagram;
00767 else
00768 ast_log(LOG_WARNING, "udptl structure is null\n");
00769 }
00770
00771 void ast_udptl_set_far_max_datagram(struct ast_udptl* udptl, int max_datagram)
00772 {
00773 if (udptl)
00774 udptl->far_max_datagram_size = max_datagram;
00775 else
00776 ast_log(LOG_WARNING, "udptl structure is null\n");
00777 }
00778
00779 struct ast_udptl *ast_udptl_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int callbackmode, struct in_addr addr)
00780 {
00781 struct ast_udptl *udptl;
00782 int x;
00783 int startplace;
00784 int i;
00785 long int flags;
00786
00787 if (!(udptl = ast_calloc(1, sizeof(*udptl))))
00788 return NULL;
00789
00790 if (udptlfectype == 2)
00791 udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_FEC;
00792 else if (udptlfectype == 1)
00793 udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_REDUNDANCY;
00794 else
00795 udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_NONE;
00796 udptl->error_correction_span = udptlfecspan;
00797 udptl->error_correction_entries = udptlfecentries;
00798
00799 udptl->far_max_datagram_size = udptlmaxdatagram;
00800 udptl->local_max_datagram_size = udptlmaxdatagram;
00801
00802 memset(&udptl->rx, 0, sizeof(udptl->rx));
00803 memset(&udptl->tx, 0, sizeof(udptl->tx));
00804 for (i = 0; i <= UDPTL_BUF_MASK; i++) {
00805 udptl->rx[i].buf_len = -1;
00806 udptl->tx[i].buf_len = -1;
00807 }
00808
00809 udptl->them.sin_family = AF_INET;
00810 udptl->us.sin_family = AF_INET;
00811
00812 if ((udptl->fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
00813 free(udptl);
00814 ast_log(LOG_WARNING, "Unable to allocate socket: %s\n", strerror(errno));
00815 return NULL;
00816 }
00817 flags = fcntl(udptl->fd, F_GETFL);
00818 fcntl(udptl->fd, F_SETFL, flags | O_NONBLOCK);
00819 #ifdef SO_NO_CHECK
00820 if (nochecksums)
00821 setsockopt(udptl->fd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
00822 #endif
00823
00824 x = (ast_random() % (udptlend - udptlstart)) + udptlstart;
00825 startplace = x;
00826 for (;;) {
00827 udptl->us.sin_port = htons(x);
00828 udptl->us.sin_addr = addr;
00829 if (bind(udptl->fd, (struct sockaddr *) &udptl->us, sizeof(udptl->us)) == 0)
00830 break;
00831 if (errno != EADDRINUSE) {
00832 ast_log(LOG_WARNING, "Unexpected bind error: %s\n", strerror(errno));
00833 close(udptl->fd);
00834 free(udptl);
00835 return NULL;
00836 }
00837 if (++x > udptlend)
00838 x = udptlstart;
00839 if (x == startplace) {
00840 ast_log(LOG_WARNING, "No UDPTL ports remaining\n");
00841 close(udptl->fd);
00842 free(udptl);
00843 return NULL;
00844 }
00845 }
00846 if (io && sched && callbackmode) {
00847
00848 udptl->sched = sched;
00849 udptl->io = io;
00850 udptl->ioid = ast_io_add(udptl->io, udptl->fd, udptlread, AST_IO_IN, udptl);
00851 }
00852 return udptl;
00853 }
00854
00855 struct ast_udptl *ast_udptl_new(struct sched_context *sched, struct io_context *io, int callbackmode)
00856 {
00857 struct in_addr ia;
00858 memset(&ia, 0, sizeof(ia));
00859 return ast_udptl_new_with_bindaddr(sched, io, callbackmode, ia);
00860 }
00861
00862 int ast_udptl_settos(struct ast_udptl *udptl, int tos)
00863 {
00864 int res;
00865
00866 if ((res = setsockopt(udptl->fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))))
00867 ast_log(LOG_WARNING, "UDPTL unable to set TOS to %d\n", tos);
00868 return res;
00869 }
00870
00871 void ast_udptl_set_peer(struct ast_udptl *udptl, struct sockaddr_in *them)
00872 {
00873 udptl->them.sin_port = them->sin_port;
00874 udptl->them.sin_addr = them->sin_addr;
00875 }
00876
00877 void ast_udptl_get_peer(struct ast_udptl *udptl, struct sockaddr_in *them)
00878 {
00879 memset(them, 0, sizeof(*them));
00880 them->sin_family = AF_INET;
00881 them->sin_port = udptl->them.sin_port;
00882 them->sin_addr = udptl->them.sin_addr;
00883 }
00884
00885 void ast_udptl_get_us(struct ast_udptl *udptl, struct sockaddr_in *us)
00886 {
00887 memcpy(us, &udptl->us, sizeof(udptl->us));
00888 }
00889
00890 void ast_udptl_stop(struct ast_udptl *udptl)
00891 {
00892 memset(&udptl->them.sin_addr, 0, sizeof(udptl->them.sin_addr));
00893 memset(&udptl->them.sin_port, 0, sizeof(udptl->them.sin_port));
00894 }
00895
00896 void ast_udptl_destroy(struct ast_udptl *udptl)
00897 {
00898 if (udptl->ioid)
00899 ast_io_remove(udptl->io, udptl->ioid);
00900 if (udptl->fd > -1)
00901 close(udptl->fd);
00902 free(udptl);
00903 }
00904
00905 int ast_udptl_write(struct ast_udptl *s, struct ast_frame *f)
00906 {
00907 int seq;
00908 int len;
00909 int res;
00910 uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
00911
00912
00913 if (s->them.sin_addr.s_addr == INADDR_ANY)
00914 return 0;
00915
00916
00917 if (f->datalen == 0)
00918 return 0;
00919
00920 if (f->frametype != AST_FRAME_MODEM) {
00921 ast_log(LOG_WARNING, "UDPTL can only send T.38 data\n");
00922 return -1;
00923 }
00924
00925
00926 seq = s->tx_seq_no & 0xFFFF;
00927
00928
00929 len = udptl_build_packet(s, buf, f->data, f->datalen);
00930
00931 if (len > 0 && s->them.sin_port && s->them.sin_addr.s_addr) {
00932 if ((res = sendto(s->fd, buf, len, 0, (struct sockaddr *) &s->them, sizeof(s->them))) < 0)
00933 ast_log(LOG_NOTICE, "UDPTL Transmission error to %s:%d: %s\n", ast_inet_ntoa(s->them.sin_addr), ntohs(s->them.sin_port), strerror(errno));
00934 #if 0
00935 printf("Sent %d bytes of UDPTL data to %s:%d\n", res, ast_inet_ntoa(udptl->them.sin_addr), ntohs(udptl->them.sin_port));
00936 #endif
00937 if (udptl_debug_test_addr(&s->them))
00938 ast_verbose("Sent UDPTL packet to %s:%d (type %d, seq %d, len %d)\n",
00939 ast_inet_ntoa(s->them.sin_addr),
00940 ntohs(s->them.sin_port), 0, seq, len);
00941 }
00942
00943 return 0;
00944 }
00945
00946 void ast_udptl_proto_unregister(struct ast_udptl_protocol *proto)
00947 {
00948 struct ast_udptl_protocol *cur;
00949 struct ast_udptl_protocol *prev;
00950
00951 cur = protos;
00952 prev = NULL;
00953 while (cur) {
00954 if (cur == proto) {
00955 if (prev)
00956 prev->next = proto->next;
00957 else
00958 protos = proto->next;
00959 return;
00960 }
00961 prev = cur;
00962 cur = cur->next;
00963 }
00964 }
00965
00966 int ast_udptl_proto_register(struct ast_udptl_protocol *proto)
00967 {
00968 struct ast_udptl_protocol *cur;
00969
00970 cur = protos;
00971 while (cur) {
00972 if (cur->type == proto->type) {
00973 ast_log(LOG_WARNING, "Tried to register same protocol '%s' twice\n", cur->type);
00974 return -1;
00975 }
00976 cur = cur->next;
00977 }
00978 proto->next = protos;
00979 protos = proto;
00980 return 0;
00981 }
00982
00983 static struct ast_udptl_protocol *get_proto(struct ast_channel *chan)
00984 {
00985 struct ast_udptl_protocol *cur;
00986
00987 cur = protos;
00988 while (cur) {
00989 if (cur->type == chan->tech->type)
00990 return cur;
00991 cur = cur->next;
00992 }
00993 return NULL;
00994 }
00995
00996 int ast_udptl_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc)
00997 {
00998 struct ast_frame *f;
00999 struct ast_channel *who;
01000 struct ast_channel *cs[3];
01001 struct ast_udptl *p0;
01002 struct ast_udptl *p1;
01003 struct ast_udptl_protocol *pr0;
01004 struct ast_udptl_protocol *pr1;
01005 struct sockaddr_in ac0;
01006 struct sockaddr_in ac1;
01007 struct sockaddr_in t0;
01008 struct sockaddr_in t1;
01009 void *pvt0;
01010 void *pvt1;
01011 int to;
01012
01013 ast_channel_lock(c0);
01014 while (ast_channel_trylock(c1)) {
01015 ast_channel_unlock(c0);
01016 usleep(1);
01017 ast_channel_lock(c0);
01018 }
01019 pr0 = get_proto(c0);
01020 pr1 = get_proto(c1);
01021 if (!pr0) {
01022 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c0->name);
01023 ast_channel_unlock(c0);
01024 ast_channel_unlock(c1);
01025 return -1;
01026 }
01027 if (!pr1) {
01028 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c1->name);
01029 ast_channel_unlock(c0);
01030 ast_channel_unlock(c1);
01031 return -1;
01032 }
01033 pvt0 = c0->tech_pvt;
01034 pvt1 = c1->tech_pvt;
01035 p0 = pr0->get_udptl_info(c0);
01036 p1 = pr1->get_udptl_info(c1);
01037 if (!p0 || !p1) {
01038
01039 ast_channel_unlock(c0);
01040 ast_channel_unlock(c1);
01041 return -2;
01042 }
01043 if (pr0->set_udptl_peer(c0, p1)) {
01044 ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", c0->name, c1->name);
01045 memset(&ac1, 0, sizeof(ac1));
01046 } else {
01047
01048 ast_udptl_get_peer(p1, &ac1);
01049 }
01050 if (pr1->set_udptl_peer(c1, p0)) {
01051 ast_log(LOG_WARNING, "Channel '%s' failed to talk back to '%s'\n", c1->name, c0->name);
01052 memset(&ac0, 0, sizeof(ac0));
01053 } else {
01054
01055 ast_udptl_get_peer(p0, &ac0);
01056 }
01057 ast_channel_unlock(c0);
01058 ast_channel_unlock(c1);
01059 cs[0] = c0;
01060 cs[1] = c1;
01061 cs[2] = NULL;
01062 for (;;) {
01063 if ((c0->tech_pvt != pvt0) ||
01064 (c1->tech_pvt != pvt1) ||
01065 (c0->masq || c0->masqr || c1->masq || c1->masqr)) {
01066 ast_log(LOG_DEBUG, "Oooh, something is weird, backing out\n");
01067
01068 return -3;
01069 }
01070 to = -1;
01071 ast_udptl_get_peer(p1, &t1);
01072 ast_udptl_get_peer(p0, &t0);
01073 if (inaddrcmp(&t1, &ac1)) {
01074 ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d\n",
01075 c1->name, ast_inet_ntoa(t1.sin_addr), ntohs(t1.sin_port));
01076 ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d\n",
01077 c1->name, ast_inet_ntoa(ac1.sin_addr), ntohs(ac1.sin_port));
01078 memcpy(&ac1, &t1, sizeof(ac1));
01079 }
01080 if (inaddrcmp(&t0, &ac0)) {
01081 ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d\n",
01082 c0->name, ast_inet_ntoa(t0.sin_addr), ntohs(t0.sin_port));
01083 ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d\n",
01084 c0->name, ast_inet_ntoa(ac0.sin_addr), ntohs(ac0.sin_port));
01085 memcpy(&ac0, &t0, sizeof(ac0));
01086 }
01087 who = ast_waitfor_n(cs, 2, &to);
01088 if (!who) {
01089 ast_log(LOG_DEBUG, "Ooh, empty read...\n");
01090
01091 if (ast_check_hangup(c0) || ast_check_hangup(c1))
01092 break;
01093 continue;
01094 }
01095 f = ast_read(who);
01096 if (!f) {
01097 *fo = f;
01098 *rc = who;
01099 ast_log(LOG_DEBUG, "Oooh, got a %s\n", f ? "digit" : "hangup");
01100
01101 return 0;
01102 } else {
01103 if (f->frametype == AST_FRAME_MODEM) {
01104
01105 if (who == c0) {
01106 ast_write(c1, f);
01107 } else if (who == c1) {
01108 ast_write(c0, f);
01109 }
01110 }
01111 ast_frfree(f);
01112 }
01113
01114 cs[2] = cs[0];
01115 cs[0] = cs[1];
01116 cs[1] = cs[2];
01117 }
01118 return -1;
01119 }
01120
01121 static int udptl_do_debug_ip(int fd, int argc, char *argv[])
01122 {
01123 struct hostent *hp;
01124 struct ast_hostent ahp;
01125 int port;
01126 char *p;
01127 char *arg;
01128
01129 port = 0;
01130 if (argc != 4)
01131 return RESULT_SHOWUSAGE;
01132 arg = argv[3];
01133 p = strstr(arg, ":");
01134 if (p) {
01135 *p = '\0';
01136 p++;
01137 port = atoi(p);
01138 }
01139 hp = ast_gethostbyname(arg, &ahp);
01140 if (hp == NULL)
01141 return RESULT_SHOWUSAGE;
01142 udptldebugaddr.sin_family = AF_INET;
01143 memcpy(&udptldebugaddr.sin_addr, hp->h_addr, sizeof(udptldebugaddr.sin_addr));
01144 udptldebugaddr.sin_port = htons(port);
01145 if (port == 0)
01146 ast_cli(fd, "UDPTL Debugging Enabled for IP: %s\n", ast_inet_ntoa(udptldebugaddr.sin_addr));
01147 else
01148 ast_cli(fd, "UDPTL Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(udptldebugaddr.sin_addr), port);
01149 udptldebug = 1;
01150 return RESULT_SUCCESS;
01151 }
01152
01153 static int udptl_do_debug(int fd, int argc, char *argv[])
01154 {
01155 if (argc != 2) {
01156 if (argc != 4)
01157 return RESULT_SHOWUSAGE;
01158 return udptl_do_debug_ip(fd, argc, argv);
01159 }
01160 udptldebug = 1;
01161 memset(&udptldebugaddr,0,sizeof(udptldebugaddr));
01162 ast_cli(fd, "UDPTL Debugging Enabled\n");
01163 return RESULT_SUCCESS;
01164 }
01165
01166 static int udptl_nodebug(int fd, int argc, char *argv[])
01167 {
01168 if (argc != 3)
01169 return RESULT_SHOWUSAGE;
01170 udptldebug = 0;
01171 ast_cli(fd,"UDPTL Debugging Disabled\n");
01172 return RESULT_SUCCESS;
01173 }
01174
01175 static char debug_usage[] =
01176 "Usage: udptl debug [ip host[:port]]\n"
01177 " Enable dumping of all UDPTL packets to and from host.\n";
01178
01179 static char nodebug_usage[] =
01180 "Usage: udptl debug off\n"
01181 " Disable all UDPTL debugging\n";
01182
01183 static struct ast_cli_entry cli_udptl_no_debug = {
01184 { "udptl", "no", "debug", NULL },
01185 udptl_nodebug, NULL,
01186 NULL };
01187
01188 static struct ast_cli_entry cli_udptl[] = {
01189 { { "udptl", "debug", NULL },
01190 udptl_do_debug, "Enable UDPTL debugging",
01191 debug_usage },
01192
01193 { { "udptl", "debug", "ip", NULL },
01194 udptl_do_debug, "Enable UDPTL debugging on IP",
01195 debug_usage },
01196
01197 { { "udptl", "debug", "off", NULL },
01198 udptl_nodebug, "Disable UDPTL debugging",
01199 nodebug_usage, NULL, &cli_udptl_no_debug },
01200 };
01201
01202 void ast_udptl_reload(void)
01203 {
01204 struct ast_config *cfg;
01205 const char *s;
01206
01207 udptlstart = 4500;
01208 udptlend = 4999;
01209 udptlfectype = 0;
01210 udptlfecentries = 0;
01211 udptlfecspan = 0;
01212 udptlmaxdatagram = 0;
01213
01214 if ((cfg = ast_config_load("udptl.conf"))) {
01215 if ((s = ast_variable_retrieve(cfg, "general", "udptlstart"))) {
01216 udptlstart = atoi(s);
01217 if (udptlstart < 1024)
01218 udptlstart = 1024;
01219 if (udptlstart > 65535)
01220 udptlstart = 65535;
01221 }
01222 if ((s = ast_variable_retrieve(cfg, "general", "udptlend"))) {
01223 udptlend = atoi(s);
01224 if (udptlend < 1024)
01225 udptlend = 1024;
01226 if (udptlend > 65535)
01227 udptlend = 65535;
01228 }
01229 if ((s = ast_variable_retrieve(cfg, "general", "udptlchecksums"))) {
01230 #ifdef SO_NO_CHECK
01231 if (ast_false(s))
01232 nochecksums = 1;
01233 else
01234 nochecksums = 0;
01235 #else
01236 if (ast_false(s))
01237 ast_log(LOG_WARNING, "Disabling UDPTL checksums is not supported on this operating system!\n");
01238 #endif
01239 }
01240 if ((s = ast_variable_retrieve(cfg, "general", "T38FaxUdpEC"))) {
01241 if (strcmp(s, "t38UDPFEC") == 0)
01242 udptlfectype = 2;
01243 else if (strcmp(s, "t38UDPRedundancy") == 0)
01244 udptlfectype = 1;
01245 }
01246 if ((s = ast_variable_retrieve(cfg, "general", "T38FaxMaxDatagram"))) {
01247 udptlmaxdatagram = atoi(s);
01248 if (udptlmaxdatagram < 0)
01249 udptlmaxdatagram = 0;
01250 if (udptlmaxdatagram > LOCAL_FAX_MAX_DATAGRAM)
01251 udptlmaxdatagram = LOCAL_FAX_MAX_DATAGRAM;
01252 }
01253 if ((s = ast_variable_retrieve(cfg, "general", "UDPTLFECentries"))) {
01254 udptlfecentries = atoi(s);
01255 if (udptlfecentries < 0)
01256 udptlfecentries = 0;
01257 if (udptlfecentries > MAX_FEC_ENTRIES)
01258 udptlfecentries = MAX_FEC_ENTRIES;
01259 }
01260 if ((s = ast_variable_retrieve(cfg, "general", "UDPTLFECspan"))) {
01261 udptlfecspan = atoi(s);
01262 if (udptlfecspan < 0)
01263 udptlfecspan = 0;
01264 if (udptlfecspan > MAX_FEC_SPAN)
01265 udptlfecspan = MAX_FEC_SPAN;
01266 }
01267 ast_config_destroy(cfg);
01268 }
01269 if (udptlstart >= udptlend) {
01270 ast_log(LOG_WARNING, "Unreasonable values for UDPTL start/end\n");
01271 udptlstart = 4500;
01272 udptlend = 4999;
01273 }
01274 if (option_verbose > 1)
01275 ast_verbose(VERBOSE_PREFIX_2 "UDPTL allocating from port range %d -> %d\n", udptlstart, udptlend);
01276 }
01277
01278 void ast_udptl_init(void)
01279 {
01280 ast_cli_register_multiple(cli_udptl, sizeof(cli_udptl) / sizeof(struct ast_cli_entry));
01281 ast_udptl_reload();
01282 }