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