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