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
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
00047 #define CALLID_NR_LEN 20
00048
00052 #define CALLID_SUFFIX_LEN ( 1 + \
00053 5 + \
00054 42 + \
00055 2 + \
00056 1 + \
00057 16 \
00058 )
00059
00060
00061 static unsigned long callid_nr;
00062 static char callid_buf[CALLID_NR_LEN + CALLID_SUFFIX_LEN];
00063
00064 static str callid_prefix;
00065 static str callid_suffix;
00066
00067
00072 int init_callid(void)
00073 {
00074 int rand_bits, i;
00075
00076
00077
00078
00079 callid_prefix.len = sizeof(unsigned long) * 2;
00080 callid_prefix.s = callid_buf;
00081
00082 if (callid_prefix.len > CALLID_NR_LEN) {
00083 LOG(L_ERR, "ERROR: Too small callid buffer\n");
00084 return -1;
00085 }
00086
00087 for(rand_bits = 1, i = RAND_MAX; i; i >>= 1, rand_bits++);
00088 i = callid_prefix.len * 4 / rand_bits;
00089
00090
00091
00092 callid_nr = rand();
00093
00094 while(i--) {
00095 callid_nr <<= rand_bits;
00096 callid_nr |= rand();
00097 }
00098
00099 i = snprintf(callid_prefix.s, callid_prefix.len + 1, "%0*lx", callid_prefix.len, callid_nr);
00100 if ((i == -1) || (i > callid_prefix.len)) {
00101 LOG(L_CRIT, "BUG: SORRY, callid calculation failed\n");
00102 return -2;
00103 }
00104
00105 DBG("Call-ID initialization: '%.*s'\n", callid_prefix.len, callid_prefix.s);
00106 return 0;
00107 }
00108
00109
00115 int child_init_callid(int rank)
00116 {
00117 struct socket_info *si;
00118
00119
00120
00121 si=bind_address?bind_address:get_first_socket();
00122 if (si==0){
00123 LOG(L_CRIT, "BUG: child_init_callid: null socket list\n");
00124 return -1;
00125 }
00126 callid_suffix.s = callid_buf + callid_prefix.len;
00127
00128 callid_suffix.len = snprintf(callid_suffix.s, CALLID_SUFFIX_LEN,
00129 "%c%d@%.*s", '-', my_pid(),
00130 si->address_str.len,
00131 si->address_str.s);
00132 if ((callid_suffix.len == -1) || (callid_suffix.len > CALLID_SUFFIX_LEN)) {
00133 LOG(L_ERR, "ERROR: child_init_callid: buffer too small\n");
00134 return -1;
00135 }
00136
00137 DBG("DEBUG: callid: '%.*s'\n", callid_prefix.len + callid_suffix.len, callid_prefix.s);
00138 return 0;
00139 }
00140
00141
00147 static inline int inc_hexchar(char* _c)
00148 {
00149 if (*_c == '9') {
00150 *_c = 'a';
00151 return 0;
00152 }
00153
00154 if (*_c == 'f') {
00155 *_c = '0';
00156 return 1;
00157 }
00158
00159 (*_c)++;
00160 return 0;
00161 }
00162
00163
00168 void generate_callid(str* callid)
00169 {
00170 int i;
00171
00172 for(i = callid_prefix.len; i; i--) {
00173 if (!inc_hexchar(callid_prefix.s + i - 1)) break;
00174 }
00175 callid->s = callid_prefix.s;
00176 callid->len = callid_prefix.len + callid_suffix.len;
00177 }