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 #include <ctype.h>
00027 #include <string.h>
00028 #include <unistd.h>
00029 #include <stdlib.h>
00030 #include <errno.h>
00031 #include <stdarg.h>
00032 #include <stdio.h>
00033 #include <sys/types.h>
00034 #include <sys/socket.h>
00035 #include <netinet/in.h>
00036 #include <arpa/inet.h>
00037
00038 #include "asterisk.h"
00039
00040 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 44955 $")
00041
00042 #include "asterisk/lock.h"
00043 #include "asterisk/io.h"
00044 #include "asterisk/logger.h"
00045 #include "asterisk/md5.h"
00046 #include "asterisk/options.h"
00047 #include "asterisk/compat.h"
00048
00049 #define AST_API_MODULE
00050 #include "asterisk/strings.h"
00051
00052 #define AST_API_MODULE
00053 #include "asterisk/time.h"
00054
00055 #define AST_API_MODULE
00056 #include "asterisk/utils.h"
00057
00058 static char base64[64];
00059 static char b2a[256];
00060
00061 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__) || defined(__CYGWIN__)
00062
00063
00064 #define ERANGE 34
00065 #undef gethostbyname
00066
00067 AST_MUTEX_DEFINE_STATIC(__mutex);
00068
00069
00070
00071
00072
00073 static int gethostbyname_r (const char *name, struct hostent *ret, char *buf,
00074 size_t buflen, struct hostent **result,
00075 int *h_errnop)
00076 {
00077 int hsave;
00078 struct hostent *ph;
00079 ast_mutex_lock(&__mutex);
00080 hsave = h_errno;
00081
00082 ph = gethostbyname(name);
00083 *h_errnop = h_errno;
00084 if (ph == NULL) {
00085 *result = NULL;
00086 } else {
00087 char **p, **q;
00088 char *pbuf;
00089 int nbytes=0;
00090 int naddr=0, naliases=0;
00091
00092
00093
00094 for (p = ph->h_addr_list; *p != 0; p++) {
00095 nbytes += ph->h_length;
00096 nbytes += sizeof(*p);
00097 naddr++;
00098 }
00099 nbytes += sizeof(*p);
00100
00101
00102 for (p = ph->h_aliases; *p != 0; p++) {
00103 nbytes += (strlen(*p)+1);
00104 nbytes += sizeof(*p);
00105 naliases++;
00106 }
00107 nbytes += sizeof(*p);
00108
00109
00110
00111 if(nbytes > buflen) {
00112 *result = NULL;
00113 ast_mutex_unlock(&__mutex);
00114 return ERANGE;
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 *ret = *ph;
00131
00132
00133 q = (char **)buf;
00134 ret->h_addr_list = q;
00135 pbuf = buf + ((naddr+naliases+2)*sizeof(*p));
00136 for (p = ph->h_addr_list; *p != 0; p++) {
00137 memcpy(pbuf, *p, ph->h_length);
00138 *q++ = pbuf;
00139 pbuf += ph->h_length;
00140 }
00141 *q++ = NULL;
00142
00143
00144 ret->h_aliases = q;
00145 for (p = ph->h_aliases; *p != 0; p++) {
00146 strcpy(pbuf, *p);
00147 *q++ = pbuf;
00148 pbuf += strlen(*p);
00149 *pbuf++ = 0;
00150 }
00151 *q++ = NULL;
00152
00153 strcpy(pbuf, ph->h_name);
00154 ret->h_name = pbuf;
00155 pbuf += strlen(ph->h_name);
00156 *pbuf++ = 0;
00157
00158 *result = ret;
00159
00160 }
00161 h_errno = hsave;
00162 ast_mutex_unlock(&__mutex);
00163
00164 return (*result == NULL);
00165 }
00166
00167
00168 #endif
00169
00170
00171
00172
00173 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp)
00174 {
00175 int res;
00176 int herrno;
00177 int dots=0;
00178 const char *s;
00179 struct hostent *result = NULL;
00180
00181
00182
00183
00184 s = host;
00185 res = 0;
00186 while(s && *s) {
00187 if (*s == '.')
00188 dots++;
00189 else if (!isdigit(*s))
00190 break;
00191 s++;
00192 }
00193 if (!s || !*s) {
00194
00195 if (dots != 3)
00196 return NULL;
00197 memset(hp, 0, sizeof(struct ast_hostent));
00198 hp->hp.h_addr_list = (void *) hp->buf;
00199 hp->hp.h_addr = hp->buf + sizeof(void *);
00200 if (inet_pton(AF_INET, host, hp->hp.h_addr) > 0)
00201 return &hp->hp;
00202 return NULL;
00203
00204 }
00205 #ifdef SOLARIS
00206 result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno);
00207
00208 if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
00209 return NULL;
00210 #else
00211 res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno);
00212
00213 if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
00214 return NULL;
00215 #endif
00216 return &hp->hp;
00217 }
00218
00219
00220
00221 AST_MUTEX_DEFINE_STATIC(test_lock);
00222 AST_MUTEX_DEFINE_STATIC(test_lock2);
00223 static pthread_t test_thread;
00224 static int lock_count = 0;
00225 static int test_errors = 0;
00226
00227
00228
00229
00230 static void *test_thread_body(void *data)
00231 {
00232 ast_mutex_lock(&test_lock);
00233 lock_count += 10;
00234 if (lock_count != 10)
00235 test_errors++;
00236 ast_mutex_lock(&test_lock);
00237 lock_count += 10;
00238 if (lock_count != 20)
00239 test_errors++;
00240 ast_mutex_lock(&test_lock2);
00241 ast_mutex_unlock(&test_lock);
00242 lock_count -= 10;
00243 if (lock_count != 10)
00244 test_errors++;
00245 ast_mutex_unlock(&test_lock);
00246 lock_count -= 10;
00247 ast_mutex_unlock(&test_lock2);
00248 if (lock_count != 0)
00249 test_errors++;
00250 return NULL;
00251 }
00252
00253 int test_for_thread_safety(void)
00254 {
00255 ast_mutex_lock(&test_lock2);
00256 ast_mutex_lock(&test_lock);
00257 lock_count += 1;
00258 ast_mutex_lock(&test_lock);
00259 lock_count += 1;
00260 ast_pthread_create(&test_thread, NULL, test_thread_body, NULL);
00261 usleep(100);
00262 if (lock_count != 2)
00263 test_errors++;
00264 ast_mutex_unlock(&test_lock);
00265 lock_count -= 1;
00266 usleep(100);
00267 if (lock_count != 1)
00268 test_errors++;
00269 ast_mutex_unlock(&test_lock);
00270 lock_count -= 1;
00271 if (lock_count != 0)
00272 test_errors++;
00273 ast_mutex_unlock(&test_lock2);
00274 usleep(100);
00275 if (lock_count != 0)
00276 test_errors++;
00277 pthread_join(test_thread, NULL);
00278 return(test_errors);
00279 }
00280
00281
00282 void ast_md5_hash(char *output, char *input)
00283 {
00284 struct MD5Context md5;
00285 unsigned char digest[16];
00286 char *ptr;
00287 int x;
00288
00289 MD5Init(&md5);
00290 MD5Update(&md5, (unsigned char *)input, strlen(input));
00291 MD5Final(digest, &md5);
00292 ptr = output;
00293 for (x=0; x<16; x++)
00294 ptr += sprintf(ptr, "%2.2x", digest[x]);
00295 }
00296
00297 int ast_base64decode(unsigned char *dst, const char *src, int max)
00298 {
00299 int cnt = 0;
00300 unsigned int byte = 0;
00301 unsigned int bits = 0;
00302 int incnt = 0;
00303 #if 0
00304 unsigned char *odst = dst;
00305 #endif
00306 while(*src && (cnt < max)) {
00307
00308 byte <<= 6;
00309 byte |= (b2a[(int)(*src)]) & 0x3f;
00310 bits += 6;
00311 #if 0
00312 printf("Add: %c %s\n", *src, binary(b2a[(int)(*src)] & 0x3f, 6));
00313 #endif
00314 src++;
00315 incnt++;
00316
00317
00318 if (bits >= 8) {
00319 bits -= 8;
00320 *dst = (byte >> bits) & 0xff;
00321 #if 0
00322 printf("Remove: %02x %s\n", *dst, binary(*dst, 8));
00323 #endif
00324 dst++;
00325 cnt++;
00326 }
00327 }
00328 #if 0
00329 dump(odst, cnt);
00330 #endif
00331
00332 return cnt;
00333 }
00334
00335 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
00336 {
00337 int cnt = 0;
00338 unsigned int byte = 0;
00339 int bits = 0;
00340 int index;
00341 int cntin = 0;
00342 #if 0
00343 char *odst = dst;
00344 dump(src, srclen);
00345 #endif
00346
00347 max--;
00348 while((cntin < srclen) && (cnt < max)) {
00349 byte <<= 8;
00350 #if 0
00351 printf("Add: %02x %s\n", *src, binary(*src, 8));
00352 #endif
00353 byte |= *(src++);
00354 bits += 8;
00355 cntin++;
00356 while((bits >= 6) && (cnt < max)) {
00357 bits -= 6;
00358
00359 index = (byte >> bits) & 0x3f;
00360 *dst = base64[index];
00361 #if 0
00362 printf("Remove: %c %s\n", *dst, binary(index, 6));
00363 #endif
00364 dst++;
00365 cnt++;
00366 }
00367 }
00368 if (bits && (cnt < max)) {
00369
00370
00371 byte <<= (6 - bits);
00372 index = (byte) & 0x3f;
00373 *(dst++) = base64[index];
00374 cnt++;
00375 }
00376 *dst = '\0';
00377 return cnt;
00378 }
00379
00380 static void base64_init(void)
00381 {
00382 int x;
00383 memset(b2a, -1, sizeof(b2a));
00384
00385 for (x=0;x<26;x++) {
00386
00387 base64[x] = 'A' + x;
00388 b2a['A' + x] = x;
00389
00390 base64[x + 26] = 'a' + x;
00391 b2a['a' + x] = x + 26;
00392
00393 if (x < 10) {
00394 base64[x + 52] = '0' + x;
00395 b2a['0' + x] = x + 52;
00396 }
00397 }
00398 base64[62] = '+';
00399 base64[63] = '/';
00400 b2a[(int)'+'] = 62;
00401 b2a[(int)'/'] = 63;
00402 }
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416 char *ast_uri_encode(char *string, char *outbuf, int buflen, int doreserved)
00417 {
00418 char *reserved = ";/?:@&=+$, ";
00419
00420 char *ptr = string;
00421 char *out = NULL;
00422 char *buf = NULL;
00423
00424 strncpy(outbuf, string, buflen);
00425
00426
00427 while (*ptr) {
00428 if (((unsigned char) *ptr) > 127 || (doreserved && strchr(reserved, *ptr)) ) {
00429
00430 if (!buf) {
00431 buf = outbuf;
00432 out = buf + (ptr - string) ;
00433 }
00434 out += sprintf(out, "%%%02x", (unsigned char) *ptr);
00435 } else if (buf) {
00436 *out = *ptr;
00437 out++;
00438 }
00439 ptr++;
00440 }
00441 if (buf)
00442 *out = '\0';
00443 return outbuf;
00444 }
00445
00446
00447 void ast_uri_decode(char *s)
00448 {
00449 char *o;
00450 unsigned int tmp;
00451
00452 for (o = s; *s; s++, o++) {
00453 if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) {
00454
00455 *o = tmp;
00456 s += 2;
00457 } else
00458 *o = *s;
00459 }
00460 *o = '\0';
00461 }
00462
00463
00464 const char *ast_inet_ntoa(char *buf, int bufsiz, struct in_addr ia)
00465 {
00466 return inet_ntop(AF_INET, &ia, buf, bufsiz);
00467 }
00468
00469 int ast_utils_init(void)
00470 {
00471 base64_init();
00472 return 0;
00473 }
00474
00475 #ifndef __linux__
00476 #undef pthread_create
00477 #endif
00478
00479 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize)
00480 {
00481 pthread_attr_t lattr;
00482 if (!attr) {
00483 pthread_attr_init(&lattr);
00484 attr = &lattr;
00485 }
00486 #ifdef __linux__
00487
00488
00489
00490
00491
00492
00493
00494 errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED);
00495 if (errno)
00496 ast_log(LOG_WARNING, "pthread_attr_setinheritsched returned non-zero: %s\n", strerror(errno));
00497 #endif
00498
00499 if (!stacksize)
00500 stacksize = AST_STACKSIZE;
00501 errno = pthread_attr_setstacksize(attr, stacksize);
00502 if (errno)
00503 ast_log(LOG_WARNING, "pthread_attr_setstacksize returned non-zero: %s\n", strerror(errno));
00504 return pthread_create(thread, attr, start_routine, data);
00505 }
00506
00507 int ast_wait_for_input(int fd, int ms)
00508 {
00509 struct pollfd pfd[1];
00510 memset(pfd, 0, sizeof(pfd));
00511 pfd[0].fd = fd;
00512 pfd[0].events = POLLIN|POLLPRI;
00513 return poll(pfd, 1, ms);
00514 }
00515
00516 char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
00517 {
00518 char *e;
00519 char *q;
00520
00521 s = ast_strip(s);
00522 if ((q = strchr(beg_quotes, *s))) {
00523 e = s + strlen(s) - 1;
00524 if (*e == *(end_quotes + (q - beg_quotes))) {
00525 s++;
00526 *e = '\0';
00527 }
00528 }
00529
00530 return s;
00531 }
00532
00533 int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap)
00534 {
00535 int result;
00536
00537 if (!buffer || !*buffer || !space || !*space)
00538 return -1;
00539
00540 result = vsnprintf(*buffer, *space, fmt, ap);
00541
00542 if (result < 0)
00543 return -1;
00544 else if (result > *space)
00545 result = *space;
00546
00547 *buffer += result;
00548 *space -= result;
00549 return 0;
00550 }
00551
00552 int ast_build_string(char **buffer, size_t *space, const char *fmt, ...)
00553 {
00554 va_list ap;
00555 int result;
00556
00557 va_start(ap, fmt);
00558 result = ast_build_string_va(buffer, space, fmt, ap);
00559 va_end(ap);
00560
00561 return result;
00562 }
00563
00564 int ast_true(const char *s)
00565 {
00566 if (ast_strlen_zero(s))
00567 return 0;
00568
00569
00570 if (!strcasecmp(s, "yes") ||
00571 !strcasecmp(s, "true") ||
00572 !strcasecmp(s, "y") ||
00573 !strcasecmp(s, "t") ||
00574 !strcasecmp(s, "1") ||
00575 !strcasecmp(s, "on"))
00576 return -1;
00577
00578 return 0;
00579 }
00580
00581 int ast_false(const char *s)
00582 {
00583 if (ast_strlen_zero(s))
00584 return 0;
00585
00586
00587 if (!strcasecmp(s, "no") ||
00588 !strcasecmp(s, "false") ||
00589 !strcasecmp(s, "n") ||
00590 !strcasecmp(s, "f") ||
00591 !strcasecmp(s, "0") ||
00592 !strcasecmp(s, "off"))
00593 return -1;
00594
00595 return 0;
00596 }
00597
00598 #define ONE_MILLION 1000000
00599
00600
00601
00602
00603 static struct timeval tvfix(struct timeval a)
00604 {
00605 if (a.tv_usec >= ONE_MILLION) {
00606 ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
00607 a.tv_sec, (long int) a.tv_usec);
00608 a.tv_sec += a.tv_usec / ONE_MILLION;
00609 a.tv_usec %= ONE_MILLION;
00610 } else if (a.tv_usec < 0) {
00611 ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
00612 a.tv_sec, (long int) a.tv_usec);
00613 a.tv_usec = 0;
00614 }
00615 return a;
00616 }
00617
00618 struct timeval ast_tvadd(struct timeval a, struct timeval b)
00619 {
00620
00621 a = tvfix(a);
00622 b = tvfix(b);
00623 a.tv_sec += b.tv_sec;
00624 a.tv_usec += b.tv_usec;
00625 if (a.tv_usec >= ONE_MILLION) {
00626 a.tv_sec++;
00627 a.tv_usec -= ONE_MILLION;
00628 }
00629 return a;
00630 }
00631
00632 struct timeval ast_tvsub(struct timeval a, struct timeval b)
00633 {
00634
00635 a = tvfix(a);
00636 b = tvfix(b);
00637 a.tv_sec -= b.tv_sec;
00638 a.tv_usec -= b.tv_usec;
00639 if (a.tv_usec < 0) {
00640 a.tv_sec-- ;
00641 a.tv_usec += ONE_MILLION;
00642 }
00643 return a;
00644 }
00645 #undef ONE_MILLION
00646
00647 #ifndef HAVE_STRCASESTR
00648 static char *upper(const char *orig, char *buf, int bufsize)
00649 {
00650 int i = 0;
00651
00652 while (i < (bufsize - 1) && orig[i]) {
00653 buf[i] = toupper(orig[i]);
00654 i++;
00655 }
00656
00657 buf[i] = '\0';
00658
00659 return buf;
00660 }
00661
00662 char *strcasestr(const char *haystack, const char *needle)
00663 {
00664 char *u1, *u2;
00665 int u1len = strlen(haystack) + 1, u2len = strlen(needle) + 1;
00666
00667 u1 = alloca(u1len);
00668 u2 = alloca(u2len);
00669 if (u1 && u2) {
00670 char *offset;
00671 if (u2len > u1len) {
00672
00673 return NULL;
00674 }
00675 offset = strstr(upper(haystack, u1, u1len), upper(needle, u2, u2len));
00676 if (offset) {
00677
00678 return ((char *)((unsigned long)haystack + (unsigned long)(offset - u1)));
00679 } else {
00680 return NULL;
00681 }
00682 } else {
00683 ast_log(LOG_ERROR, "Out of memory\n");
00684 return NULL;
00685 }
00686 }
00687 #endif
00688
00689 #ifndef HAVE_STRNLEN
00690 size_t strnlen(const char *s, size_t n)
00691 {
00692 size_t len;
00693
00694 for (len=0; len < n; len++)
00695 if (s[len] == '\0')
00696 break;
00697
00698 return len;
00699 }
00700 #endif
00701
00702 #if !defined(HAVE_STRNDUP) && !defined(__AST_DEBUG_MALLOC)
00703 char *strndup(const char *s, size_t n)
00704 {
00705 size_t len = strnlen(s, n);
00706 char *new = malloc(len + 1);
00707
00708 if (!new)
00709 return NULL;
00710
00711 new[len] = '\0';
00712 return memcpy(new, s, len);
00713 }
00714 #endif
00715
00716 #if !defined(HAVE_VASPRINTF) && !defined(__AST_DEBUG_MALLOC)
00717 int vasprintf(char **strp, const char *fmt, va_list ap)
00718 {
00719 int size;
00720 va_list ap2;
00721 char s;
00722
00723 *strp = NULL;
00724 va_copy(ap2, ap);
00725 size = vsnprintf(&s, 1, fmt, ap2);
00726 va_end(ap2);
00727 *strp = malloc(size + 1);
00728 if (!*strp)
00729 return -1;
00730 vsnprintf(*strp, size + 1, fmt, ap);
00731
00732 return size;
00733 }
00734 #endif
00735
00736 #ifndef HAVE_STRTOQ
00737 #ifndef LONG_MIN
00738 #define LONG_MIN (-9223372036854775807L-1L)
00739
00740 #endif
00741 #ifndef LONG_MAX
00742 #define LONG_MAX 9223372036854775807L
00743
00744 #endif
00745
00746
00747
00748
00749
00750
00751
00752 uint64_t strtoq(const char *nptr, char **endptr, int base)
00753 {
00754 const char *s;
00755 uint64_t acc;
00756 unsigned char c;
00757 uint64_t qbase, cutoff;
00758 int neg, any, cutlim;
00759
00760
00761
00762
00763
00764
00765 s = nptr;
00766 do {
00767 c = *s++;
00768 } while (isspace(c));
00769 if (c == '-') {
00770 neg = 1;
00771 c = *s++;
00772 } else {
00773 neg = 0;
00774 if (c == '+')
00775 c = *s++;
00776 }
00777 if ((base == 0 || base == 16) &&
00778 c == '\0' && (*s == 'x' || *s == 'X')) {
00779 c = s[1];
00780 s += 2;
00781 base = 16;
00782 }
00783 if (base == 0)
00784 base = c == '\0' ? 8 : 10;
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804 qbase = (unsigned)base;
00805 cutoff = neg ? (uint64_t)-(LONG_MIN + LONG_MAX) + LONG_MAX : LONG_MAX;
00806 cutlim = cutoff % qbase;
00807 cutoff /= qbase;
00808 for (acc = 0, any = 0;; c = *s++) {
00809 if (!isascii(c))
00810 break;
00811 if (isdigit(c))
00812 c -= '\0';
00813 else if (isalpha(c))
00814 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
00815 else
00816 break;
00817 if (c >= base)
00818 break;
00819 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
00820 any = -1;
00821 else {
00822 any = 1;
00823 acc *= qbase;
00824 acc += c;
00825 }
00826 }
00827 if (any < 0) {
00828 acc = neg ? LONG_MIN : LONG_MAX;
00829 } else if (neg)
00830 acc = -acc;
00831 if (endptr != 0)
00832 *((const char **)endptr) = any ? s - 1 : nptr;
00833 return acc;
00834 }
00835 #endif
00836
00837 #ifndef HAVE_GETLOADAVG
00838 #ifdef linux
00839
00840 int getloadavg(double *list, int nelem)
00841 {
00842 FILE *LOADAVG;
00843 double avg[3] = { 0.0, 0.0, 0.0 };
00844 int i, res = -1;
00845
00846 if ((LOADAVG = fopen("/proc/loadavg", "r"))) {
00847 fscanf(LOADAVG, "%lf %lf %lf", &avg[0], &avg[1], &avg[2]);
00848 res = 0;
00849 fclose(LOADAVG);
00850 }
00851
00852 for (i = 0; (i < nelem) && (i < 3); i++) {
00853 list[i] = avg[i];
00854 }
00855
00856 return res;
00857 }
00858 #else
00859
00860
00861 int getloadavg(double *list, int nelem)
00862 {
00863 int i;
00864
00865 for (i = 0; i < nelem; i++) {
00866 list[i] = 0.1;
00867 }
00868 return -1;
00869 }
00870 #endif
00871 #endif
00872
00873 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
00874 {
00875 char *dataPut = start;
00876 int inEscape = 0;
00877 int inQuotes = 0;
00878
00879 for (; *start; start++) {
00880 if (inEscape) {
00881 *dataPut++ = *start;
00882 inEscape = 0;
00883 } else {
00884 if (*start == '\\') {
00885 inEscape = 1;
00886 } else if (*start == '\'') {
00887 inQuotes = 1-inQuotes;
00888 } else {
00889
00890 *dataPut++ = inQuotes ? *start : ((*start==find) ? replace_with : *start);
00891 }
00892 }
00893 }
00894 if (start != dataPut)
00895 *dataPut = 0;
00896 return dataPut;
00897 }
00898
00899 void ast_enable_packet_fragmentation(int sock)
00900 {
00901 #ifdef __linux__
00902 int val = IP_PMTUDISC_DONT;
00903
00904 if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)))
00905 ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
00906 #endif
00907 }
00908