callid.c
Go to the documentation of this file.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 #include <stdio.h>
00038 #include <stdlib.h>
00039 #include "../../dprint.h"
00040 #include "../../pt.h"
00041 #include "../../socket_info.h"
00042 #include "callid.h"
00043
00044 #define CALLID_NR_LEN 20
00045
00046
00047
00048
00049
00050
00051 #define CALLID_SUFFIX_LEN ( 1 + \
00052 5 + \
00053 42 + \
00054 2 + \
00055 1 + \
00056 16 \
00057 )
00058
00059 #define CID_SEP '-'
00060
00061 static unsigned long callid_nr;
00062 static char callid_buf[CALLID_NR_LEN + CALLID_SUFFIX_LEN];
00063
00064 str callid_prefix;
00065 str callid_suffix;
00066
00067
00068
00069
00070
00071 int init_callid(void)
00072 {
00073 int rand_bits, i;
00074
00075
00076
00077
00078 callid_prefix.len = sizeof(unsigned long) * 2;
00079 callid_prefix.s = callid_buf;
00080
00081 if (callid_prefix.len > CALLID_NR_LEN) {
00082 LM_ERR("too small callid buffer\n");
00083 return -1;
00084 }
00085
00086 for(rand_bits = 1, i = RAND_MAX; i; i >>= 1, rand_bits++);
00087 i = callid_prefix.len * 4 / rand_bits;
00088
00089
00090 callid_nr = rand();
00091
00092 while(i--) {
00093 callid_nr <<= rand_bits;
00094 callid_nr |= rand();
00095 }
00096
00097 i = snprintf(callid_prefix.s, callid_prefix.len + 1, "%0*lx", callid_prefix.len, callid_nr);
00098 if ((i == -1) || (i > callid_prefix.len)) {
00099 LM_CRIT("callid calculation failed\n");
00100 return -2;
00101 }
00102
00103 LM_DBG("Call-ID initialization: '%.*s'\n", callid_prefix.len, callid_prefix.s);
00104 return 0;
00105 }
00106
00107
00108
00109
00110
00111 int child_init_callid(int rank)
00112 {
00113 struct socket_info *si;
00114
00115
00116
00117 si=bind_address?bind_address:get_first_socket();
00118 if (si==0){
00119 LM_CRIT("null socket list\n");
00120 return -1;
00121 }
00122 callid_suffix.s = callid_buf + callid_prefix.len;
00123
00124 callid_suffix.len = snprintf(callid_suffix.s, CALLID_SUFFIX_LEN,
00125 "%c%d@%.*s", CID_SEP, my_pid(),
00126 si->address_str.len,
00127 si->address_str.s);
00128 if ((callid_suffix.len == -1) || (callid_suffix.len > CALLID_SUFFIX_LEN)) {
00129 LM_ERR("buffer too small\n");
00130 return -1;
00131 }
00132
00133 LM_DBG("callid: '%.*s'\n", callid_prefix.len + callid_suffix.len, callid_prefix.s);
00134 return 0;
00135 }
00136
00137
00138
00139
00140
00141
00142 static inline int inc_hexchar(char* _c)
00143 {
00144 if (*_c == '9') {
00145 *_c = 'a';
00146 return 0;
00147 }
00148
00149 if (*_c == 'f') {
00150 *_c = '0';
00151 return 1;
00152 }
00153
00154 (*_c)++;
00155 return 0;
00156 }
00157
00158
00159
00160
00161
00162 void generate_callid(str* callid)
00163 {
00164 int i;
00165
00166 for(i = callid_prefix.len; i; i--) {
00167 if (!inc_hexchar(callid_prefix.s + i - 1)) break;
00168 }
00169 callid->s = callid_prefix.s;
00170 callid->len = callid_prefix.len + callid_suffix.len;
00171 }