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
00050
00051
00052 #include "asterisk.h"
00053
00054 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 244385 $")
00055
00056 #include <sys/time.h>
00057 #include <signal.h>
00058 #include <fcntl.h>
00059
00060 #include "asterisk/udptl.h"
00061 #include "asterisk/frame.h"
00062 #include "asterisk/channel.h"
00063 #include "asterisk/acl.h"
00064 #include "asterisk/config.h"
00065 #include "asterisk/lock.h"
00066 #include "asterisk/utils.h"
00067 #include "asterisk/netsock.h"
00068 #include "asterisk/cli.h"
00069 #include "asterisk/unaligned.h"
00070
00071 #define UDPTL_MTU 1200
00072
00073 #if !defined(FALSE)
00074 #define FALSE 0
00075 #endif
00076 #if !defined(TRUE)
00077 #define TRUE (!FALSE)
00078 #endif
00079
00080 #define LOG_TAG(u) S_OR(u->tag, "no tag")
00081
00082 static int udptlstart = 4500;
00083 static int udptlend = 4599;
00084 static int udptldebug;
00085 static struct sockaddr_in udptldebugaddr;
00086 #ifdef SO_NO_CHECK
00087 static int nochecksums;
00088 #endif
00089 static int udptlfecentries;
00090 static int udptlfecspan;
00091 static int use_even_ports;
00092
00093 #define LOCAL_FAX_MAX_DATAGRAM 1400
00094 #define DEFAULT_FAX_MAX_DATAGRAM 400
00095 #define FAX_MAX_DATAGRAM_LIMIT 1400
00096 #define MAX_FEC_ENTRIES 5
00097 #define MAX_FEC_SPAN 5
00098
00099 #define UDPTL_BUF_MASK 15
00100
00101 typedef struct {
00102 int buf_len;
00103 uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
00104 } udptl_fec_tx_buffer_t;
00105
00106 typedef struct {
00107 int buf_len;
00108 uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
00109 unsigned int fec_len[MAX_FEC_ENTRIES];
00110 uint8_t fec[MAX_FEC_ENTRIES][LOCAL_FAX_MAX_DATAGRAM];
00111 unsigned int fec_span;
00112 unsigned int fec_entries;
00113 } udptl_fec_rx_buffer_t;
00114
00115
00116 struct ast_udptl {
00117 int fd;
00118 char resp;
00119 struct ast_frame f[16];
00120 unsigned char rawdata[8192 + AST_FRIENDLY_OFFSET];
00121 unsigned int lasteventseqn;
00122 int nat;
00123 int flags;
00124 struct sockaddr_in us;
00125 struct sockaddr_in them;
00126 int *ioid;
00127 struct sched_context *sched;
00128 struct io_context *io;
00129 void *data;
00130 char *tag;
00131 ast_udptl_callback callback;
00132
00133
00134
00135
00136 enum ast_t38_ec_modes error_correction_scheme;
00137
00138
00139
00140
00141 unsigned int error_correction_entries;
00142
00143
00144
00145
00146 unsigned int error_correction_span;
00147
00148
00149
00150
00151 int far_max_datagram;
00152
00153
00154
00155
00156
00157 int local_max_datagram;
00158
00159
00160
00161
00162
00163
00164
00165 int far_max_ifp;
00166
00167
00168
00169
00170
00171 int local_max_ifp;
00172
00173 int verbose;
00174
00175 struct sockaddr_in far;
00176
00177 unsigned int tx_seq_no;
00178 unsigned int rx_seq_no;
00179 unsigned int rx_expected_seq_no;
00180
00181 udptl_fec_tx_buffer_t tx[UDPTL_BUF_MASK + 1];
00182 udptl_fec_rx_buffer_t rx[UDPTL_BUF_MASK + 1];
00183 };
00184
00185 static AST_RWLIST_HEAD_STATIC(protos, ast_udptl_protocol);
00186
00187 static inline int udptl_debug_test_addr(const struct sockaddr_in *addr)
00188 {
00189 if (udptldebug == 0)
00190 return 0;
00191 if (udptldebugaddr.sin_addr.s_addr) {
00192 if (((ntohs(udptldebugaddr.sin_port) != 0) &&
00193 (udptldebugaddr.sin_port != addr->sin_port)) ||
00194 (udptldebugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
00195 return 0;
00196 }
00197 return 1;
00198 }
00199
00200 static int decode_length(uint8_t *buf, unsigned int limit, unsigned int *len, unsigned int *pvalue)
00201 {
00202 if (*len >= limit)
00203 return -1;
00204 if ((buf[*len] & 0x80) == 0) {
00205 *pvalue = buf[*len];
00206 (*len)++;
00207 return 0;
00208 }
00209 if ((buf[*len] & 0x40) == 0) {
00210 if (*len == limit - 1)
00211 return -1;
00212 *pvalue = (buf[*len] & 0x3F) << 8;
00213 (*len)++;
00214 *pvalue |= buf[*len];
00215 (*len)++;
00216 return 0;
00217 }
00218 *pvalue = (buf[*len] & 0x3F) << 14;
00219 (*len)++;
00220
00221 return 1;
00222 }
00223
00224
00225 static int decode_open_type(uint8_t *buf, unsigned int limit, unsigned int *len, const uint8_t **p_object, unsigned int *p_num_octets)
00226 {
00227 unsigned int octet_cnt;
00228 unsigned int octet_idx;
00229 unsigned int length;
00230 unsigned int i;
00231 const uint8_t **pbuf;
00232
00233 for (octet_idx = 0, *p_num_octets = 0; ; octet_idx += octet_cnt) {
00234 octet_cnt = 0;
00235 if ((length = decode_length(buf, limit, len, &octet_cnt)) < 0)
00236 return -1;
00237 if (octet_cnt > 0) {
00238 *p_num_octets += octet_cnt;
00239
00240 pbuf = &p_object[octet_idx];
00241 i = 0;
00242
00243 if ((*len + octet_cnt) > limit)
00244 return -1;
00245
00246 *pbuf = &buf[*len];
00247 *len += octet_cnt;
00248 }
00249 if (length == 0)
00250 break;
00251 }
00252 return 0;
00253 }
00254
00255
00256 static unsigned int encode_length(uint8_t *buf, unsigned int *len, unsigned int value)
00257 {
00258 unsigned int multiplier;
00259
00260 if (value < 0x80) {
00261
00262 buf[*len] = value;
00263 (*len)++;
00264 return value;
00265 }
00266 if (value < 0x4000) {
00267
00268
00269 buf[*len] = ((0x8000 | value) >> 8) & 0xFF;
00270 (*len)++;
00271 buf[*len] = value & 0xFF;
00272 (*len)++;
00273 return value;
00274 }
00275
00276 multiplier = (value < 0x10000) ? (value >> 14) : 4;
00277
00278 buf[*len] = 0xC0 | multiplier;
00279 (*len)++;
00280 return multiplier << 14;
00281 }
00282
00283
00284 static int encode_open_type(const struct ast_udptl *udptl, uint8_t *buf, unsigned int buflen,
00285 unsigned int *len, const uint8_t *data, unsigned int num_octets)
00286 {
00287 unsigned int enclen;
00288 unsigned int octet_idx;
00289 uint8_t zero_byte;
00290
00291
00292 if (num_octets == 0) {
00293 zero_byte = 0;
00294 data = &zero_byte;
00295 num_octets = 1;
00296 }
00297
00298 for (octet_idx = 0; ; num_octets -= enclen, octet_idx += enclen) {
00299 if ((enclen = encode_length(buf, len, num_octets)) < 0)
00300 return -1;
00301 if (enclen + *len > buflen) {
00302 ast_log(LOG_ERROR, "(%s): Buffer overflow detected (%d + %d > %d)\n",
00303 LOG_TAG(udptl), enclen, *len, buflen);
00304 return -1;
00305 }
00306 if (enclen > 0) {
00307 memcpy(&buf[*len], &data[octet_idx], enclen);
00308 *len += enclen;
00309 }
00310 if (enclen >= num_octets)
00311 break;
00312 }
00313
00314 return 0;
00315 }
00316
00317
00318 static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, unsigned int len)
00319 {
00320 int stat1;
00321 int stat2;
00322 int i;
00323 int j;
00324 int k;
00325 int l;
00326 int m;
00327 int x;
00328 int limit;
00329 int which;
00330 unsigned int ptr;
00331 unsigned int count;
00332 int total_count;
00333 int seq_no;
00334 const uint8_t *ifp;
00335 const uint8_t *data;
00336 unsigned int ifp_len;
00337 int repaired[16];
00338 const uint8_t *bufs[16];
00339 unsigned int lengths[16];
00340 int span;
00341 int entries;
00342 int ifp_no;
00343
00344 ptr = 0;
00345 ifp_no = 0;
00346 memset(&s->f[0], 0, sizeof(s->f[0]));
00347
00348
00349 if (ptr + 2 > len)
00350 return -1;
00351 seq_no = (buf[0] << 8) | buf[1];
00352 ptr += 2;
00353
00354
00355 if ((stat1 = decode_open_type(buf, len, &ptr, &ifp, &ifp_len)) != 0)
00356 return -1;
00357
00358 if (ptr + 1 > len)
00359 return -1;
00360 if ((buf[ptr++] & 0x80) == 0) {
00361
00362 if (seq_no > s->rx_seq_no) {
00363
00364
00365 total_count = 0;
00366 do {
00367 if ((stat2 = decode_length(buf, len, &ptr, &count)) < 0)
00368 return -1;
00369 for (i = 0; i < count; i++) {
00370 if ((stat1 = decode_open_type(buf, len, &ptr, &bufs[total_count + i], &lengths[total_count + i])) != 0)
00371 return -1;
00372 }
00373 total_count += count;
00374 }
00375 while (stat2 > 0);
00376
00377 for (i = total_count; i > 0; i--) {
00378 if (seq_no - i >= s->rx_seq_no) {
00379
00380
00381
00382 s->f[ifp_no].frametype = AST_FRAME_MODEM;
00383 s->f[ifp_no].subclass = AST_MODEM_T38;
00384
00385 s->f[ifp_no].mallocd = 0;
00386 s->f[ifp_no].seqno = seq_no - i;
00387 s->f[ifp_no].datalen = lengths[i - 1];
00388 s->f[ifp_no].data.ptr = (uint8_t *) bufs[i - 1];
00389 s->f[ifp_no].offset = 0;
00390 s->f[ifp_no].src = "UDPTL";
00391 if (ifp_no > 0)
00392 AST_LIST_NEXT(&s->f[ifp_no - 1], frame_list) = &s->f[ifp_no];
00393 AST_LIST_NEXT(&s->f[ifp_no], frame_list) = NULL;
00394 ifp_no++;
00395 }
00396 }
00397 }
00398 }
00399 else
00400 {
00401
00402
00403 if (ifp_len > LOCAL_FAX_MAX_DATAGRAM)
00404 return -1;
00405
00406 for ( ; seq_no > s->rx_seq_no; s->rx_seq_no++) {
00407 x = s->rx_seq_no & UDPTL_BUF_MASK;
00408 s->rx[x].buf_len = -1;
00409 s->rx[x].fec_len[0] = 0;
00410 s->rx[x].fec_span = 0;
00411 s->rx[x].fec_entries = 0;
00412 }
00413
00414 x = seq_no & UDPTL_BUF_MASK;
00415
00416 memset(repaired, 0, sizeof(repaired));
00417
00418
00419 memcpy(s->rx[x].buf, ifp, ifp_len);
00420 s->rx[x].buf_len = ifp_len;
00421 repaired[x] = TRUE;
00422
00423
00424
00425
00426 if (ptr + 2 > len)
00427 return -1;
00428 if (buf[ptr++] != 1)
00429 return -1;
00430 span = buf[ptr++];
00431 s->rx[x].fec_span = span;
00432
00433
00434
00435 if (ptr + 1 > len)
00436 return -1;
00437 entries = buf[ptr++];
00438 s->rx[x].fec_entries = entries;
00439
00440
00441 for (i = 0; i < entries; i++) {
00442 if ((stat1 = decode_open_type(buf, len, &ptr, &data, &s->rx[x].fec_len[i])) != 0)
00443 return -1;
00444 if (s->rx[x].fec_len[i] > LOCAL_FAX_MAX_DATAGRAM)
00445 return -1;
00446
00447
00448 memcpy(s->rx[x].fec[i], data, s->rx[x].fec_len[i]);
00449 #if 0
00450 fprintf(stderr, "FEC: ");
00451 for (j = 0; j < s->rx[x].fec_len[i]; j++)
00452 fprintf(stderr, "%02X ", data[j]);
00453 fprintf(stderr, "\n");
00454 #endif
00455 }
00456
00457
00458
00459 for (l = x; l != ((x - (16 - span*entries)) & UDPTL_BUF_MASK); l = (l - 1) & UDPTL_BUF_MASK) {
00460 if (s->rx[l].fec_len[0] <= 0)
00461 continue;
00462 for (m = 0; m < s->rx[l].fec_entries; m++) {
00463 limit = (l + m) & UDPTL_BUF_MASK;
00464 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) {
00465 if (s->rx[k].buf_len <= 0)
00466 which = (which == -1) ? k : -2;
00467 }
00468 if (which >= 0) {
00469
00470 for (j = 0; j < s->rx[l].fec_len[m]; j++) {
00471 s->rx[which].buf[j] = s->rx[l].fec[m][j];
00472 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)
00473 s->rx[which].buf[j] ^= (s->rx[k].buf_len > j) ? s->rx[k].buf[j] : 0;
00474 }
00475 s->rx[which].buf_len = s->rx[l].fec_len[m];
00476 repaired[which] = TRUE;
00477 }
00478 }
00479 }
00480
00481 for (l = (x + 1) & UDPTL_BUF_MASK, j = seq_no - UDPTL_BUF_MASK; l != x; l = (l + 1) & UDPTL_BUF_MASK, j++) {
00482 if (repaired[l]) {
00483
00484 s->f[ifp_no].frametype = AST_FRAME_MODEM;
00485 s->f[ifp_no].subclass = AST_MODEM_T38;
00486
00487 s->f[ifp_no].mallocd = 0;
00488 s->f[ifp_no].seqno = j;
00489 s->f[ifp_no].datalen = s->rx[l].buf_len;
00490 s->f[ifp_no].data.ptr = s->rx[l].buf;
00491 s->f[ifp_no].offset = 0;
00492 s->f[ifp_no].src = "UDPTL";
00493 if (ifp_no > 0)
00494 AST_LIST_NEXT(&s->f[ifp_no - 1], frame_list) = &s->f[ifp_no];
00495 AST_LIST_NEXT(&s->f[ifp_no], frame_list) = NULL;
00496 ifp_no++;
00497 }
00498 }
00499 }
00500
00501
00502
00503 if (seq_no >= s->rx_seq_no) {
00504
00505 s->f[ifp_no].frametype = AST_FRAME_MODEM;
00506 s->f[ifp_no].subclass = AST_MODEM_T38;
00507
00508 s->f[ifp_no].mallocd = 0;
00509 s->f[ifp_no].seqno = seq_no;
00510 s->f[ifp_no].datalen = ifp_len;
00511 s->f[ifp_no].data.ptr = (uint8_t *) ifp;
00512 s->f[ifp_no].offset = 0;
00513 s->f[ifp_no].src = "UDPTL";
00514 if (ifp_no > 0)
00515 AST_LIST_NEXT(&s->f[ifp_no - 1], frame_list) = &s->f[ifp_no];
00516 AST_LIST_NEXT(&s->f[ifp_no], frame_list) = NULL;
00517
00518 ifp_no++;
00519 }
00520
00521 s->rx_seq_no = seq_no + 1;
00522 return ifp_no;
00523 }
00524
00525
00526 static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, unsigned int buflen, uint8_t *ifp, unsigned int ifp_len)
00527 {
00528 uint8_t fec[LOCAL_FAX_MAX_DATAGRAM * 2];
00529 int i;
00530 int j;
00531 int seq;
00532 int entry;
00533 int entries;
00534 int span;
00535 int m;
00536 unsigned int len;
00537 int limit;
00538 int high_tide;
00539
00540 seq = s->tx_seq_no & 0xFFFF;
00541
00542
00543 entry = seq & UDPTL_BUF_MASK;
00544
00545
00546
00547 s->tx[entry].buf_len = ifp_len;
00548 memcpy(s->tx[entry].buf, ifp, ifp_len);
00549
00550
00551
00552 len = 0;
00553
00554 buf[len++] = (seq >> 8) & 0xFF;
00555 buf[len++] = seq & 0xFF;
00556
00557
00558 if (encode_open_type(s, buf, buflen, &len, ifp, ifp_len) < 0)
00559 return -1;
00560
00561
00562 switch (s->error_correction_scheme)
00563 {
00564 case UDPTL_ERROR_CORRECTION_NONE:
00565
00566 buf[len++] = 0x00;
00567
00568
00569 if (encode_length(buf, &len, 0) < 0)
00570 return -1;
00571 break;
00572 case UDPTL_ERROR_CORRECTION_REDUNDANCY:
00573
00574 buf[len++] = 0x00;
00575 if (s->tx_seq_no > s->error_correction_entries)
00576 entries = s->error_correction_entries;
00577 else
00578 entries = s->tx_seq_no;
00579
00580
00581 if (encode_length(buf, &len, entries) < 0)
00582 return -1;
00583
00584 for (i = 0; i < entries; i++) {
00585 j = (entry - i - 1) & UDPTL_BUF_MASK;
00586 if (encode_open_type(s, buf, buflen, &len, s->tx[j].buf, s->tx[j].buf_len) < 0) {
00587 ast_debug(1, "(%s): Encoding failed at i=%d, j=%d\n",
00588 LOG_TAG(s), i, j);
00589 return -1;
00590 }
00591 }
00592 break;
00593 case UDPTL_ERROR_CORRECTION_FEC:
00594 span = s->error_correction_span;
00595 entries = s->error_correction_entries;
00596 if (seq < s->error_correction_span*s->error_correction_entries) {
00597
00598 entries = seq/s->error_correction_span;
00599 if (seq < s->error_correction_span)
00600 span = 0;
00601 }
00602
00603 buf[len++] = 0x80;
00604
00605
00606 buf[len++] = 1;
00607 buf[len++] = span;
00608
00609
00610 buf[len++] = entries;
00611 for (m = 0; m < entries; m++) {
00612
00613 limit = (entry + m) & UDPTL_BUF_MASK;
00614 high_tide = 0;
00615 for (i = (limit - span*entries) & UDPTL_BUF_MASK; i != limit; i = (i + entries) & UDPTL_BUF_MASK) {
00616 if (high_tide < s->tx[i].buf_len) {
00617 for (j = 0; j < high_tide; j++)
00618 fec[j] ^= s->tx[i].buf[j];
00619 for ( ; j < s->tx[i].buf_len; j++)
00620 fec[j] = s->tx[i].buf[j];
00621 high_tide = s->tx[i].buf_len;
00622 } else {
00623 for (j = 0; j < s->tx[i].buf_len; j++)
00624 fec[j] ^= s->tx[i].buf[j];
00625 }
00626 }
00627 if (encode_open_type(s, buf, buflen, &len, fec, high_tide) < 0)
00628 return -1;
00629 }
00630 break;
00631 }
00632
00633 if (s->verbose)
00634 fprintf(stderr, "\n");
00635
00636 s->tx_seq_no++;
00637 return len;
00638 }
00639
00640 int ast_udptl_fd(const struct ast_udptl *udptl)
00641 {
00642 return udptl->fd;
00643 }
00644
00645 void ast_udptl_set_data(struct ast_udptl *udptl, void *data)
00646 {
00647 udptl->data = data;
00648 }
00649
00650 void ast_udptl_set_callback(struct ast_udptl *udptl, ast_udptl_callback callback)
00651 {
00652 udptl->callback = callback;
00653 }
00654
00655 void ast_udptl_setnat(struct ast_udptl *udptl, int nat)
00656 {
00657 udptl->nat = nat;
00658 }
00659
00660 static int udptlread(int *id, int fd, short events, void *cbdata)
00661 {
00662 struct ast_udptl *udptl = cbdata;
00663 struct ast_frame *f;
00664
00665 if ((f = ast_udptl_read(udptl))) {
00666 if (udptl->callback)
00667 udptl->callback(udptl, f, udptl->data);
00668 }
00669 return 1;
00670 }
00671
00672 struct ast_frame *ast_udptl_read(struct ast_udptl *udptl)
00673 {
00674 int res;
00675 struct sockaddr_in sin;
00676 socklen_t len;
00677 uint16_t seqno = 0;
00678 uint16_t *udptlheader;
00679
00680 len = sizeof(sin);
00681
00682
00683 res = recvfrom(udptl->fd,
00684 udptl->rawdata + AST_FRIENDLY_OFFSET,
00685 sizeof(udptl->rawdata) - AST_FRIENDLY_OFFSET,
00686 0,
00687 (struct sockaddr *) &sin,
00688 &len);
00689 udptlheader = (uint16_t *)(udptl->rawdata + AST_FRIENDLY_OFFSET);
00690 if (res < 0) {
00691 if (errno != EAGAIN)
00692 ast_log(LOG_WARNING, "(%s): UDPTL read error: %s\n",
00693 LOG_TAG(udptl), strerror(errno));
00694 ast_assert(errno != EBADF);
00695 return &ast_null_frame;
00696 }
00697
00698
00699 if (!udptl->them.sin_addr.s_addr || !udptl->them.sin_port)
00700 return &ast_null_frame;
00701
00702 if (udptl->nat) {
00703
00704 if ((udptl->them.sin_addr.s_addr != sin.sin_addr.s_addr) ||
00705 (udptl->them.sin_port != sin.sin_port)) {
00706 memcpy(&udptl->them, &sin, sizeof(udptl->them));
00707 ast_debug(1, "UDPTL NAT (%s): Using address %s:%d\n",
00708 LOG_TAG(udptl), ast_inet_ntoa(udptl->them.sin_addr), ntohs(udptl->them.sin_port));
00709 }
00710 }
00711
00712 if (udptl_debug_test_addr(&sin)) {
00713 ast_verb(1, "UDPTL (%s): packet from %s:%d (type %d, seq %d, len %d)\n",
00714 LOG_TAG(udptl), ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), 0, seqno, res);
00715 }
00716 if (udptl_rx_packet(udptl, udptl->rawdata + AST_FRIENDLY_OFFSET, res) < 1)
00717 return &ast_null_frame;
00718
00719 return &udptl->f[0];
00720 }
00721
00722 static void calculate_local_max_datagram(struct ast_udptl *udptl)
00723 {
00724 unsigned int new_max = 0;
00725
00726 if (udptl->local_max_ifp == -1) {
00727 ast_log(LOG_WARNING, "(%s): Cannot calculate local_max_datagram before local_max_ifp has been set.\n",
00728 LOG_TAG(udptl));
00729 udptl->local_max_datagram = -1;
00730 return;
00731 }
00732
00733
00734
00735
00736
00737
00738
00739 switch (udptl->error_correction_scheme) {
00740 case UDPTL_ERROR_CORRECTION_NONE:
00741
00742
00743
00744 new_max = 5 + udptl->local_max_ifp;
00745 break;
00746 case UDPTL_ERROR_CORRECTION_REDUNDANCY:
00747
00748
00749
00750 new_max = 5 + udptl->local_max_ifp + 2 + (3 * udptl->local_max_ifp);
00751 break;
00752 case UDPTL_ERROR_CORRECTION_FEC:
00753
00754
00755
00756 new_max = 5 + udptl->local_max_ifp + 4 + udptl->local_max_ifp;
00757 break;
00758 }
00759
00760 udptl->local_max_datagram = MIN(new_max * 1.05, LOCAL_FAX_MAX_DATAGRAM);
00761 }
00762
00763 static void calculate_far_max_ifp(struct ast_udptl *udptl)
00764 {
00765 unsigned new_max = 0;
00766
00767 if (udptl->far_max_datagram == -1) {
00768 ast_log(LOG_WARNING, "(%s): Cannot calculate far_max_ifp before far_max_datagram has been set.\n",
00769 LOG_TAG(udptl));
00770 udptl->far_max_ifp = -1;
00771 return;
00772 }
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787 switch (udptl->error_correction_scheme) {
00788 case UDPTL_ERROR_CORRECTION_NONE:
00789
00790
00791
00792 new_max = udptl->far_max_datagram - 5;
00793 break;
00794 case UDPTL_ERROR_CORRECTION_REDUNDANCY:
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807 for ( ;
00808 (new_max < 80) && (udptl->error_correction_entries > 1);
00809 --udptl->error_correction_entries) {
00810 new_max = (udptl->far_max_datagram - 8) / (udptl->error_correction_entries + 1);
00811 }
00812 break;
00813 case UDPTL_ERROR_CORRECTION_FEC:
00814
00815
00816
00817 new_max = (udptl->far_max_datagram - 10) / 2;
00818 break;
00819 }
00820
00821 udptl->far_max_ifp = new_max * 0.95;
00822 }
00823
00824 enum ast_t38_ec_modes ast_udptl_get_error_correction_scheme(const struct ast_udptl *udptl)
00825 {
00826 return udptl->error_correction_scheme;
00827 }
00828
00829 void ast_udptl_set_error_correction_scheme(struct ast_udptl *udptl, enum ast_t38_ec_modes ec)
00830 {
00831 udptl->error_correction_scheme = ec;
00832 switch (ec) {
00833 case UDPTL_ERROR_CORRECTION_FEC:
00834 udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_FEC;
00835 if (udptl->error_correction_entries == 0) {
00836 udptl->error_correction_entries = 3;
00837 }
00838 if (udptl->error_correction_span == 0) {
00839 udptl->error_correction_span = 3;
00840 }
00841 break;
00842 case UDPTL_ERROR_CORRECTION_REDUNDANCY:
00843 udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_REDUNDANCY;
00844 if (udptl->error_correction_entries == 0) {
00845 udptl->error_correction_entries = 3;
00846 }
00847 break;
00848 default:
00849
00850 break;
00851 };
00852
00853 udptl->local_max_datagram = -1;
00854 udptl->far_max_ifp = -1;
00855 }
00856
00857 void ast_udptl_set_local_max_ifp(struct ast_udptl *udptl, unsigned int max_ifp)
00858 {
00859
00860
00861 if ((signed int) max_ifp > 0) {
00862 udptl->local_max_ifp = max_ifp;
00863
00864 udptl->local_max_datagram = -1;
00865 }
00866 }
00867
00868 unsigned int ast_udptl_get_local_max_datagram(struct ast_udptl *udptl)
00869 {
00870 if (udptl->local_max_datagram == -1) {
00871 calculate_local_max_datagram(udptl);
00872 }
00873
00874
00875 if (udptl->local_max_datagram < 0) {
00876 return 0;
00877 }
00878 return udptl->local_max_datagram;
00879 }
00880
00881 void ast_udptl_set_far_max_datagram(struct ast_udptl *udptl, unsigned int max_datagram)
00882 {
00883 if (!max_datagram || (max_datagram > FAX_MAX_DATAGRAM_LIMIT)) {
00884 udptl->far_max_datagram = DEFAULT_FAX_MAX_DATAGRAM;
00885 } else {
00886 udptl->far_max_datagram = max_datagram;
00887 }
00888
00889 udptl->far_max_ifp = -1;
00890 }
00891
00892 unsigned int ast_udptl_get_far_max_datagram(const struct ast_udptl *udptl)
00893 {
00894 if (udptl->far_max_datagram < 0) {
00895 return 0;
00896 }
00897 return udptl->far_max_datagram;
00898 }
00899
00900 unsigned int ast_udptl_get_far_max_ifp(struct ast_udptl *udptl)
00901 {
00902 if (udptl->far_max_ifp == -1) {
00903 calculate_far_max_ifp(udptl);
00904 }
00905
00906 if (udptl->far_max_ifp < 0) {
00907 return 0;
00908 }
00909 return udptl->far_max_ifp;
00910 }
00911
00912 struct ast_udptl *ast_udptl_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int callbackmode, struct in_addr addr)
00913 {
00914 struct ast_udptl *udptl;
00915 int x;
00916 int startplace;
00917 int i;
00918 long int flags;
00919
00920 if (!(udptl = ast_calloc(1, sizeof(*udptl))))
00921 return NULL;
00922
00923 udptl->error_correction_span = udptlfecspan;
00924 udptl->error_correction_entries = udptlfecentries;
00925
00926 udptl->far_max_datagram = -1;
00927 udptl->far_max_ifp = -1;
00928 udptl->local_max_ifp = -1;
00929 udptl->local_max_datagram = -1;
00930
00931 for (i = 0; i <= UDPTL_BUF_MASK; i++) {
00932 udptl->rx[i].buf_len = -1;
00933 udptl->tx[i].buf_len = -1;
00934 }
00935
00936 udptl->them.sin_family = AF_INET;
00937 udptl->us.sin_family = AF_INET;
00938
00939 if ((udptl->fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
00940 ast_free(udptl);
00941 ast_log(LOG_WARNING, "Unable to allocate socket: %s\n", strerror(errno));
00942 return NULL;
00943 }
00944 flags = fcntl(udptl->fd, F_GETFL);
00945 fcntl(udptl->fd, F_SETFL, flags | O_NONBLOCK);
00946 #ifdef SO_NO_CHECK
00947 if (nochecksums)
00948 setsockopt(udptl->fd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
00949 #endif
00950
00951 x = (udptlstart == udptlend) ? udptlstart : (ast_random() % (udptlend - udptlstart)) + udptlstart;
00952 if (use_even_ports && (x & 1)) {
00953 ++x;
00954 }
00955 startplace = x;
00956 for (;;) {
00957 udptl->us.sin_port = htons(x);
00958 udptl->us.sin_addr = addr;
00959 if (bind(udptl->fd, (struct sockaddr *) &udptl->us, sizeof(udptl->us)) == 0)
00960 break;
00961 if (errno != EADDRINUSE) {
00962 ast_log(LOG_WARNING, "Unexpected bind error: %s\n", strerror(errno));
00963 close(udptl->fd);
00964 ast_free(udptl);
00965 return NULL;
00966 }
00967 if (use_even_ports) {
00968 x += 2;
00969 } else {
00970 ++x;
00971 }
00972 if (x > udptlend)
00973 x = udptlstart;
00974 if (x == startplace) {
00975 ast_log(LOG_WARNING, "No UDPTL ports remaining\n");
00976 close(udptl->fd);
00977 ast_free(udptl);
00978 return NULL;
00979 }
00980 }
00981 if (io && sched && callbackmode) {
00982
00983 udptl->sched = sched;
00984 udptl->io = io;
00985 udptl->ioid = ast_io_add(udptl->io, udptl->fd, udptlread, AST_IO_IN, udptl);
00986 }
00987 return udptl;
00988 }
00989
00990 struct ast_udptl *ast_udptl_new(struct sched_context *sched, struct io_context *io, int callbackmode)
00991 {
00992 struct in_addr ia;
00993 memset(&ia, 0, sizeof(ia));
00994 return ast_udptl_new_with_bindaddr(sched, io, callbackmode, ia);
00995 }
00996
00997 void ast_udptl_set_tag(struct ast_udptl *udptl, const char *format, ...)
00998 {
00999 va_list ap;
01000
01001 if (udptl->tag) {
01002 ast_free(udptl->tag);
01003 udptl->tag = NULL;
01004 }
01005 va_start(ap, format);
01006 if (ast_vasprintf(&udptl->tag, format, ap) == -1) {
01007 udptl->tag = NULL;
01008 }
01009 va_end(ap);
01010 }
01011
01012 int ast_udptl_setqos(struct ast_udptl *udptl, unsigned int tos, unsigned int cos)
01013 {
01014 return ast_netsock_set_qos(udptl->fd, tos, cos, "UDPTL");
01015 }
01016
01017 void ast_udptl_set_peer(struct ast_udptl *udptl, const struct sockaddr_in *them)
01018 {
01019 udptl->them.sin_port = them->sin_port;
01020 udptl->them.sin_addr = them->sin_addr;
01021 }
01022
01023 void ast_udptl_get_peer(const struct ast_udptl *udptl, struct sockaddr_in *them)
01024 {
01025 memset(them, 0, sizeof(*them));
01026 them->sin_family = AF_INET;
01027 them->sin_port = udptl->them.sin_port;
01028 them->sin_addr = udptl->them.sin_addr;
01029 }
01030
01031 void ast_udptl_get_us(const struct ast_udptl *udptl, struct sockaddr_in *us)
01032 {
01033 memcpy(us, &udptl->us, sizeof(udptl->us));
01034 }
01035
01036 void ast_udptl_stop(struct ast_udptl *udptl)
01037 {
01038 memset(&udptl->them.sin_addr, 0, sizeof(udptl->them.sin_addr));
01039 memset(&udptl->them.sin_port, 0, sizeof(udptl->them.sin_port));
01040 }
01041
01042 void ast_udptl_destroy(struct ast_udptl *udptl)
01043 {
01044 if (udptl->ioid)
01045 ast_io_remove(udptl->io, udptl->ioid);
01046 if (udptl->fd > -1)
01047 close(udptl->fd);
01048 if (udptl->tag)
01049 ast_free(udptl->tag);
01050 ast_free(udptl);
01051 }
01052
01053 int ast_udptl_write(struct ast_udptl *s, struct ast_frame *f)
01054 {
01055 unsigned int seq;
01056 unsigned int len = f->datalen;
01057 int res;
01058
01059 const int bufsize = (s->far_max_datagram > 0) ? s->far_max_datagram : DEFAULT_FAX_MAX_DATAGRAM;
01060 uint8_t buf[bufsize];
01061
01062 memset(buf, 0, sizeof(buf));
01063
01064
01065 if (s->them.sin_addr.s_addr == INADDR_ANY)
01066 return 0;
01067
01068
01069 if (f->datalen == 0)
01070 return 0;
01071
01072 if ((f->frametype != AST_FRAME_MODEM) ||
01073 (f->subclass != AST_MODEM_T38)) {
01074 ast_log(LOG_WARNING, "(%s): UDPTL can only send T.38 data.\n",
01075 LOG_TAG(s));
01076 return -1;
01077 }
01078
01079 if (len > s->far_max_ifp) {
01080 ast_log(LOG_WARNING,
01081 "(%s): UDPTL asked to send %d bytes of IFP when far end only prepared to accept %d bytes; data loss will occur."
01082 "You may need to override the T38FaxMaxDatagram value for this endpoint in the channel driver configuration.\n",
01083 LOG_TAG(s), len, s->far_max_ifp);
01084 len = s->far_max_ifp;
01085 }
01086
01087
01088 seq = s->tx_seq_no & 0xFFFF;
01089
01090
01091 len = udptl_build_packet(s, buf, sizeof(buf), f->data.ptr, len);
01092
01093 if (len > 0 && s->them.sin_port && s->them.sin_addr.s_addr) {
01094 if ((res = sendto(s->fd, buf, len, 0, (struct sockaddr *) &s->them, sizeof(s->them))) < 0)
01095 ast_log(LOG_NOTICE, "(%s): UDPTL Transmission error to %s:%d: %s\n",
01096 LOG_TAG(s), ast_inet_ntoa(s->them.sin_addr), ntohs(s->them.sin_port), strerror(errno));
01097 if (udptl_debug_test_addr(&s->them))
01098 ast_verb(1, "UDPTL (%s): packet to %s:%d (type %d, seq %d, len %d)\n",
01099 LOG_TAG(s), ast_inet_ntoa(s->them.sin_addr), ntohs(s->them.sin_port), 0, seq, len);
01100 }
01101
01102 return 0;
01103 }
01104
01105 void ast_udptl_proto_unregister(struct ast_udptl_protocol *proto)
01106 {
01107 AST_RWLIST_WRLOCK(&protos);
01108 AST_RWLIST_REMOVE(&protos, proto, list);
01109 AST_RWLIST_UNLOCK(&protos);
01110 }
01111
01112 int ast_udptl_proto_register(struct ast_udptl_protocol *proto)
01113 {
01114 struct ast_udptl_protocol *cur;
01115
01116 AST_RWLIST_WRLOCK(&protos);
01117 AST_RWLIST_TRAVERSE(&protos, cur, list) {
01118 if (cur->type == proto->type) {
01119 ast_log(LOG_WARNING, "Tried to register same protocol '%s' twice\n", cur->type);
01120 AST_RWLIST_UNLOCK(&protos);
01121 return -1;
01122 }
01123 }
01124 AST_RWLIST_INSERT_TAIL(&protos, proto, list);
01125 AST_RWLIST_UNLOCK(&protos);
01126 return 0;
01127 }
01128
01129 static struct ast_udptl_protocol *get_proto(struct ast_channel *chan)
01130 {
01131 struct ast_udptl_protocol *cur = NULL;
01132
01133 AST_RWLIST_RDLOCK(&protos);
01134 AST_RWLIST_TRAVERSE(&protos, cur, list) {
01135 if (cur->type == chan->tech->type)
01136 break;
01137 }
01138 AST_RWLIST_UNLOCK(&protos);
01139
01140 return cur;
01141 }
01142
01143 int ast_udptl_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc)
01144 {
01145 struct ast_frame *f;
01146 struct ast_channel *who;
01147 struct ast_channel *cs[3];
01148 struct ast_udptl *p0;
01149 struct ast_udptl *p1;
01150 struct ast_udptl_protocol *pr0;
01151 struct ast_udptl_protocol *pr1;
01152 struct sockaddr_in ac0;
01153 struct sockaddr_in ac1;
01154 struct sockaddr_in t0;
01155 struct sockaddr_in t1;
01156 void *pvt0;
01157 void *pvt1;
01158 int to;
01159
01160 ast_channel_lock(c0);
01161 while (ast_channel_trylock(c1)) {
01162 ast_channel_unlock(c0);
01163 usleep(1);
01164 ast_channel_lock(c0);
01165 }
01166 pr0 = get_proto(c0);
01167 pr1 = get_proto(c1);
01168 if (!pr0) {
01169 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c0->name);
01170 ast_channel_unlock(c0);
01171 ast_channel_unlock(c1);
01172 return -1;
01173 }
01174 if (!pr1) {
01175 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c1->name);
01176 ast_channel_unlock(c0);
01177 ast_channel_unlock(c1);
01178 return -1;
01179 }
01180 pvt0 = c0->tech_pvt;
01181 pvt1 = c1->tech_pvt;
01182 p0 = pr0->get_udptl_info(c0);
01183 p1 = pr1->get_udptl_info(c1);
01184 if (!p0 || !p1) {
01185
01186 ast_channel_unlock(c0);
01187 ast_channel_unlock(c1);
01188 return -2;
01189 }
01190 if (pr0->set_udptl_peer(c0, p1)) {
01191 ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", c0->name, c1->name);
01192 memset(&ac1, 0, sizeof(ac1));
01193 } else {
01194
01195 ast_udptl_get_peer(p1, &ac1);
01196 }
01197 if (pr1->set_udptl_peer(c1, p0)) {
01198 ast_log(LOG_WARNING, "Channel '%s' failed to talk back to '%s'\n", c1->name, c0->name);
01199 memset(&ac0, 0, sizeof(ac0));
01200 } else {
01201
01202 ast_udptl_get_peer(p0, &ac0);
01203 }
01204 ast_channel_unlock(c0);
01205 ast_channel_unlock(c1);
01206 cs[0] = c0;
01207 cs[1] = c1;
01208 cs[2] = NULL;
01209 for (;;) {
01210 if ((c0->tech_pvt != pvt0) ||
01211 (c1->tech_pvt != pvt1) ||
01212 (c0->masq || c0->masqr || c1->masq || c1->masqr)) {
01213 ast_debug(1, "Oooh, something is weird, backing out\n");
01214
01215 return -3;
01216 }
01217 to = -1;
01218 ast_udptl_get_peer(p1, &t1);
01219 ast_udptl_get_peer(p0, &t0);
01220 if (inaddrcmp(&t1, &ac1)) {
01221 ast_debug(1, "Oooh, '%s' changed end address to %s:%d\n",
01222 c1->name, ast_inet_ntoa(t1.sin_addr), ntohs(t1.sin_port));
01223 ast_debug(1, "Oooh, '%s' was %s:%d\n",
01224 c1->name, ast_inet_ntoa(ac1.sin_addr), ntohs(ac1.sin_port));
01225 memcpy(&ac1, &t1, sizeof(ac1));
01226 }
01227 if (inaddrcmp(&t0, &ac0)) {
01228 ast_debug(1, "Oooh, '%s' changed end address to %s:%d\n",
01229 c0->name, ast_inet_ntoa(t0.sin_addr), ntohs(t0.sin_port));
01230 ast_debug(1, "Oooh, '%s' was %s:%d\n",
01231 c0->name, ast_inet_ntoa(ac0.sin_addr), ntohs(ac0.sin_port));
01232 memcpy(&ac0, &t0, sizeof(ac0));
01233 }
01234 who = ast_waitfor_n(cs, 2, &to);
01235 if (!who) {
01236 ast_debug(1, "Ooh, empty read...\n");
01237
01238 if (ast_check_hangup(c0) || ast_check_hangup(c1))
01239 break;
01240 continue;
01241 }
01242 f = ast_read(who);
01243 if (!f) {
01244 *fo = f;
01245 *rc = who;
01246 ast_debug(1, "Oooh, got a %s\n", f ? "digit" : "hangup");
01247
01248 return 0;
01249 } else {
01250 if (f->frametype == AST_FRAME_MODEM) {
01251
01252 if (who == c0) {
01253 ast_write(c1, f);
01254 } else if (who == c1) {
01255 ast_write(c0, f);
01256 }
01257 }
01258 ast_frfree(f);
01259 }
01260
01261 cs[2] = cs[0];
01262 cs[0] = cs[1];
01263 cs[1] = cs[2];
01264 }
01265 return -1;
01266 }
01267
01268 static char *handle_cli_udptl_debug_deprecated(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
01269 {
01270 struct hostent *hp;
01271 struct ast_hostent ahp;
01272 int port;
01273 char *p;
01274 char *arg;
01275
01276 switch (cmd) {
01277 case CLI_INIT:
01278 e->command = "udptl debug [off|ip]";
01279 e->usage =
01280 "Usage: udptl debug [off]|[ip host[:port]]\n"
01281 " Enable or disable dumping of UDPTL packets.\n"
01282 " If ip is specified, limit the dumped packets to those to and from\n"
01283 " the specified 'host' with optional port.\n";
01284 return NULL;
01285 case CLI_GENERATE:
01286 return NULL;
01287 }
01288
01289 if (a->argc < 2 || a->argc > 4)
01290 return CLI_SHOWUSAGE;
01291
01292 if (a->argc == 2) {
01293 udptldebug = 1;
01294 memset(&udptldebugaddr, 0, sizeof(udptldebugaddr));
01295 ast_cli(a->fd, "UDPTL Debugging Enabled\n");
01296 } else if (a->argc == 3) {
01297 if (strncasecmp(a->argv[2], "off", 3))
01298 return CLI_SHOWUSAGE;
01299 udptldebug = 0;
01300 ast_cli(a->fd, "UDPTL Debugging Disabled\n");
01301 } else {
01302 if (strncasecmp(a->argv[2], "ip", 2))
01303 return CLI_SHOWUSAGE;
01304 port = 0;
01305 arg = a->argv[3];
01306 p = strstr(arg, ":");
01307 if (p) {
01308 *p = '\0';
01309 p++;
01310 port = atoi(p);
01311 }
01312 hp = ast_gethostbyname(arg, &ahp);
01313 if (hp == NULL)
01314 return CLI_SHOWUSAGE;
01315 udptldebugaddr.sin_family = AF_INET;
01316 memcpy(&udptldebugaddr.sin_addr, hp->h_addr, sizeof(udptldebugaddr.sin_addr));
01317 udptldebugaddr.sin_port = htons(port);
01318 if (port == 0)
01319 ast_cli(a->fd, "UDPTL Debugging Enabled for IP: %s\n", ast_inet_ntoa(udptldebugaddr.sin_addr));
01320 else
01321 ast_cli(a->fd, "UDPTL Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(udptldebugaddr.sin_addr), port);
01322 udptldebug = 1;
01323 }
01324
01325 return CLI_SUCCESS;
01326 }
01327
01328 static char *handle_cli_udptl_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
01329 {
01330 struct hostent *hp;
01331 struct ast_hostent ahp;
01332 int port;
01333 char *p;
01334 char *arg;
01335
01336 switch (cmd) {
01337 case CLI_INIT:
01338 e->command = "udptl set debug {on|off|ip}";
01339 e->usage =
01340 "Usage: udptl set debug {on|off|ip host[:port]}\n"
01341 " Enable or disable dumping of UDPTL packets.\n"
01342 " If ip is specified, limit the dumped packets to those to and from\n"
01343 " the specified 'host' with optional port.\n";
01344 return NULL;
01345 case CLI_GENERATE:
01346 return NULL;
01347 }
01348
01349 if (a->argc < 4 || a->argc > 5)
01350 return CLI_SHOWUSAGE;
01351
01352 if (a->argc == 4) {
01353 if (!strncasecmp(a->argv[3], "on", 2)) {
01354 udptldebug = 1;
01355 memset(&udptldebugaddr, 0, sizeof(udptldebugaddr));
01356 ast_cli(a->fd, "UDPTL Debugging Enabled\n");
01357 } else if (!strncasecmp(a->argv[3], "off", 3)) {
01358 udptldebug = 0;
01359 ast_cli(a->fd, "UDPTL Debugging Disabled\n");
01360 } else {
01361 return CLI_SHOWUSAGE;
01362 }
01363 } else {
01364 if (strncasecmp(a->argv[3], "ip", 2))
01365 return CLI_SHOWUSAGE;
01366 port = 0;
01367 arg = a->argv[4];
01368 p = strstr(arg, ":");
01369 if (p) {
01370 *p = '\0';
01371 p++;
01372 port = atoi(p);
01373 }
01374 hp = ast_gethostbyname(arg, &ahp);
01375 if (hp == NULL)
01376 return CLI_SHOWUSAGE;
01377 udptldebugaddr.sin_family = AF_INET;
01378 memcpy(&udptldebugaddr.sin_addr, hp->h_addr, sizeof(udptldebugaddr.sin_addr));
01379 udptldebugaddr.sin_port = htons(port);
01380 if (port == 0)
01381 ast_cli(a->fd, "UDPTL Debugging Enabled for IP: %s\n", ast_inet_ntoa(udptldebugaddr.sin_addr));
01382 else
01383 ast_cli(a->fd, "UDPTL Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(udptldebugaddr.sin_addr), port);
01384 udptldebug = 1;
01385 }
01386
01387 return CLI_SUCCESS;
01388 }
01389
01390 static struct ast_cli_entry cli_handle_udptl_debug_deprecated = AST_CLI_DEFINE(handle_cli_udptl_debug_deprecated, "Enable/Disable UDPTL debugging");
01391
01392 static struct ast_cli_entry cli_udptl[] = {
01393 AST_CLI_DEFINE(handle_cli_udptl_set_debug, "Enable/Disable UDPTL debugging", .deprecate_cmd = &cli_handle_udptl_debug_deprecated)
01394 };
01395
01396 static void __ast_udptl_reload(int reload)
01397 {
01398 struct ast_config *cfg;
01399 const char *s;
01400 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
01401
01402 if ((cfg = ast_config_load2("udptl.conf", "udptl", config_flags)) == CONFIG_STATUS_FILEUNCHANGED)
01403 return;
01404
01405 udptlstart = 4500;
01406 udptlend = 4999;
01407 udptlfecentries = 0;
01408 udptlfecspan = 0;
01409 use_even_ports = 0;
01410
01411 if (cfg) {
01412 if ((s = ast_variable_retrieve(cfg, "general", "udptlstart"))) {
01413 udptlstart = atoi(s);
01414 if (udptlstart < 1024) {
01415 ast_log(LOG_WARNING, "Ports under 1024 are not allowed for T.38.\n");
01416 udptlstart = 1024;
01417 }
01418 if (udptlstart > 65535) {
01419 ast_log(LOG_WARNING, "Ports over 65535 are invalid.\n");
01420 udptlstart = 65535;
01421 }
01422 }
01423 if ((s = ast_variable_retrieve(cfg, "general", "udptlend"))) {
01424 udptlend = atoi(s);
01425 if (udptlend < 1024) {
01426 ast_log(LOG_WARNING, "Ports under 1024 are not allowed for T.38.\n");
01427 udptlend = 1024;
01428 }
01429 if (udptlend > 65535) {
01430 ast_log(LOG_WARNING, "Ports over 65535 are invalid.\n");
01431 udptlend = 65535;
01432 }
01433 }
01434 if ((s = ast_variable_retrieve(cfg, "general", "udptlchecksums"))) {
01435 #ifdef SO_NO_CHECK
01436 if (ast_false(s))
01437 nochecksums = 1;
01438 else
01439 nochecksums = 0;
01440 #else
01441 if (ast_false(s))
01442 ast_log(LOG_WARNING, "Disabling UDPTL checksums is not supported on this operating system!\n");
01443 #endif
01444 }
01445 if ((s = ast_variable_retrieve(cfg, "general", "T38FaxUdpEC"))) {
01446 ast_log(LOG_WARNING, "T38FaxUdpEC in udptl.conf is no longer supported; use the t38pt_udptl configuration option in sip.conf instead.\n");
01447 }
01448 if ((s = ast_variable_retrieve(cfg, "general", "T38FaxMaxDatagram"))) {
01449 ast_log(LOG_WARNING, "T38FaxMaxDatagram in udptl.conf is no longer supported; value is now supplied by T.38 applications.\n");
01450 }
01451 if ((s = ast_variable_retrieve(cfg, "general", "UDPTLFECEntries"))) {
01452 udptlfecentries = atoi(s);
01453 if (udptlfecentries < 1) {
01454 ast_log(LOG_WARNING, "Too small UDPTLFECEntries value. Defaulting to 1.\n");
01455 udptlfecentries = 1;
01456 }
01457 if (udptlfecentries > MAX_FEC_ENTRIES) {
01458 ast_log(LOG_WARNING, "Too large UDPTLFECEntries value. Defaulting to %d.\n", MAX_FEC_ENTRIES);
01459 udptlfecentries = MAX_FEC_ENTRIES;
01460 }
01461 }
01462 if ((s = ast_variable_retrieve(cfg, "general", "UDPTLFECSpan"))) {
01463 udptlfecspan = atoi(s);
01464 if (udptlfecspan < 1) {
01465 ast_log(LOG_WARNING, "Too small UDPTLFECSpan value. Defaulting to 1.\n");
01466 udptlfecspan = 1;
01467 }
01468 if (udptlfecspan > MAX_FEC_SPAN) {
01469 ast_log(LOG_WARNING, "Too large UDPTLFECSpan value. Defaulting to %d.\n", MAX_FEC_SPAN);
01470 udptlfecspan = MAX_FEC_SPAN;
01471 }
01472 }
01473 if ((s = ast_variable_retrieve(cfg, "general", "use_even_ports"))) {
01474 use_even_ports = ast_true(s);
01475 }
01476 ast_config_destroy(cfg);
01477 }
01478 if (udptlstart >= udptlend) {
01479 ast_log(LOG_WARNING, "Unreasonable values for UDPTL start/end ports; defaulting to 4500-4999.\n");
01480 udptlstart = 4500;
01481 udptlend = 4999;
01482 }
01483 if (use_even_ports && (udptlstart & 1)) {
01484 ++udptlstart;
01485 ast_log(LOG_NOTICE, "Odd numbered udptlstart specified but use_even_ports enabled. udptlstart is now %d\n", udptlstart);
01486 }
01487 if (use_even_ports && (udptlend & 1)) {
01488 --udptlend;
01489 ast_log(LOG_NOTICE, "Odd numbered udptlend specified but use_event_ports enabled. udptlend is now %d\n", udptlend);
01490 }
01491 ast_verb(2, "UDPTL allocating from port range %d -> %d\n", udptlstart, udptlend);
01492 }
01493
01494 int ast_udptl_reload(void)
01495 {
01496 __ast_udptl_reload(1);
01497 return 0;
01498 }
01499
01500 void ast_udptl_init(void)
01501 {
01502 ast_cli_register_multiple(cli_udptl, sizeof(cli_udptl) / sizeof(struct ast_cli_entry));
01503 __ast_udptl_reload(0);
01504 }