/** * enforce a response coming from a UE to contain the same Via headers sent in the corresponding request * @param rpl - the SIP reply * @param str1 - not used * @param str2 - not used * @returns true if ok, false if not or error */ int P_enforce_via_list(struct sip_msg *rpl,char *str1, char *str2) { static struct hdr_field * h = NULL; str hdr; cscf_del_all_headers(rpl, HDR_VIA_T); struct sip_msg *req = cscf_get_request_from_reply(rpl); if (!req){ LOG(L_ERR,"ERR:"M_NAME":P_enforce_via_list: No transactional request found.\n"); return CSCF_RETURN_FALSE; } h = cscf_get_next_via_hdr(req,0); while (h) { hdr.len = h->body.len + via_hdr_s.len + via_hdr_e.len; hdr.s = pkg_malloc(hdr.len); if (!hdr.s) { LOG(L_ERR, "ERR:"M_NAME":P_enforce_via_list: cannot alloc bytes : %d", hdr.len); } hdr.len=0; STR_APPEND(hdr, via_hdr_s); STR_APPEND(hdr, h->body); STR_APPEND(hdr, via_hdr_e); cscf_add_header_first(rpl, &hdr, HDR_VIA_T); h = cscf_get_next_via_hdr(req,h); } return CSCF_RETURN_TRUE; }
/** * Check if we already did record-route * @param msg - the SIP message to add to * @param str1 - direction - "orig" or "term" * @param str2 - not used * @returns #CSCF_RETURN_TRUE if ok, #CSCF_RETURN_FALSE if not or #CSCF_RETURN_BREAK on error */ int S_is_record_routed(struct sip_msg *msg,char *str1,char *str2) { str rr; str u = {0,0},scheme={0,0},scscf={0,0}; struct hdr_field *hdr=0; rr_t *rr_s; enum s_dialog_direction dir = get_dialog_direction(str1); switch (dir){ case DLG_MOBILE_ORIGINATING: STR_PKG_DUP(rr,scscf_record_route_mo,"pkg"); break; case DLG_MOBILE_TERMINATING: STR_PKG_DUP(rr,scscf_record_route_mt,"pkg"); break; default: u.s = str1; u.len = strlen(str1); if (scscf_name_str.len>4 && strncasecmp(scscf_name_str.s,"sip:",4)==0){ scheme.s = scscf_name_str.s; scheme.len = 4; }else if (scscf_name_str.len>5 && strncasecmp(scscf_name_str.s,"sips:",5)==0){ scheme.s = scscf_name_str.s; scheme.len = 4; } scscf.s = scheme.s+scheme.len; scscf.len = scscf_name_str.len - scheme.len; rr.len = scheme.len+u.len+1+scscf.len; rr.s = pkg_malloc(rr.len); if (!rr.s){ LOG(L_ERR,"ERR:"M_NAME":S_record_route: error allocating %d bytes!\n",rr.len); return CSCF_RETURN_BREAK; } rr.len = 0; STR_APPEND(rr,scheme); STR_APPEND(rr,u); rr.s[rr.len++]='@'; STR_APPEND(rr,scscf); } for(hdr = cscf_get_next_record_route(msg,(struct hdr_field*) 0); hdr ; hdr = cscf_get_next_record_route(msg,hdr)){ for (rr_s = (rr_t *)hdr->parsed;rr_s; rr_s = rr_s->next) if (rr_s->nameaddr.uri.len == rr.len && strncasecmp(rr_s->nameaddr.uri.s,rr.s,rr.len)==0){ pkg_free(rr.s); return CSCF_RETURN_TRUE; } } pkg_free(rr.s); return CSCF_RETURN_FALSE; out_of_memory: return CSCF_RETURN_ERROR; }
/** * Inserts the Route header containing the Service-Route to be enforced * @param msg - the SIP message to add to * @param str1 - the value to insert (IBCF URI here) - !!! quoted if needed * @param str2 - not used * @returns #CSCF_RETURN_TRUE if ok or #CSCF_RETURN_ERROR on error */ int P_route_to_IBCF(struct sip_msg *msg,char *str1,char*str2) { str newuri={0,0}; str uri; str x; int add_lr=0; static str lr_param={";lr",3}; /* Get char *str1 into str uri */ uri.s = str1; uri.len = strlen(str1); x.len = route_s.len + uri.len + route_e.len; /* Add ;lr if there's not in the URI */ if (!strstr(str1,";lr")){ add_lr=1; x.len+=lr_param.len; } x.s = pkg_malloc(x.len); if (!x.s){ LOG(L_ERR, "ERR:"M_NAME":P_route_to_IBCF: Error allocating %d bytes\n",x.len); x.len=0; return CSCF_RETURN_ERROR; } /* Get complete Route header into x */ x.len=0; STR_APPEND(x,route_s); STR_APPEND(x,uri); if (add_lr) STR_APPEND(x,lr_param); STR_APPEND(x,route_e); /* Set dst_uri to the topmost Route URI */ newuri.s = pkg_malloc(uri.len); if (!newuri.s){ LOG(L_ERR, "ERR:"M_NAME":P_route_to_IBCF: Error allocating %d bytes\n",uri.len); return CSCF_RETURN_ERROR; } newuri.len = uri.len; memcpy(newuri.s,uri.s,newuri.len); if (msg->dst_uri.s) pkg_free(msg->dst_uri.s); msg->dst_uri = newuri; /* Add those Route header in x into msg */ if (cscf_add_header_first(msg,&x,HDR_ROUTE_T)) return CSCF_RETURN_TRUE; else { LOG(L_ERR,"ERR:"M_NAME":P_route_to_IBCF: Failed to add new Route.\n"); if (x.s) pkg_free(x.s); return CSCF_RETURN_ERROR; } }
/** * Record routes, with given user as parameter. * @param msg - the SIP message to add to * @param str1 - direction - "orig" or "term" * @param str2 - not used * @returns #CSCF_RETURN_TRUE if ok, #CSCF_RETURN_FALSE if not or #CSCF_RETURN_BREAK on error */ int S_record_route(struct sip_msg *msg,char *str1,char *str2) { str rr={0,0}; str u = {0,0},scheme={0,0},scscf={0,0}; enum s_dialog_direction dir = get_dialog_direction(str1); switch (dir){ case DLG_MOBILE_ORIGINATING: STR_PKG_DUP(rr,scscf_record_route_mo,"pkg"); break; case DLG_MOBILE_TERMINATING: STR_PKG_DUP(rr,scscf_record_route_mt,"pkg"); break; default: u.s = str1; u.len = strlen(str1); if (scscf_name_str.len>4 && strncasecmp(scscf_name_str.s,"sip:",4)==0){ scheme.s = scscf_name_str.s; scheme.len = 4; }else if (scscf_name_str.len>5 && strncasecmp(scscf_name_str.s,"sips:",5)==0){ scheme.s = scscf_name_str.s; scheme.len = 4; } scscf.s = scheme.s+scheme.len; scscf.len = scscf_name_str.len - scheme.len; rr.len = s_record_route_s.len+scheme.len+u.len+1+scscf.len+s_record_route_e.len; rr.s = pkg_malloc(rr.len); if (!rr.s){ LOG(L_ERR,"ERR:"M_NAME":S_record_route: error allocating %d bytes!\n",rr.len); return CSCF_RETURN_BREAK; } rr.len = 0; STR_APPEND(rr,s_record_route_s); STR_APPEND(rr,scheme); STR_APPEND(rr,u); rr.s[rr.len++]='@'; STR_APPEND(rr,scscf); STR_APPEND(rr,s_record_route_e); } if (cscf_add_header_first(msg,&rr,HDR_RECORDROUTE_T)) return CSCF_RETURN_TRUE; else{ if (rr.s) pkg_free(rr.s); return CSCF_RETURN_BREAK; } out_of_memory: return CSCF_RETURN_BREAK; }
/** * Enforce a response coming from a UE to contain the same Record Route headers sent in the * corresponding request. * @param msg - the SIP reply * @param str1 - not used * @param str2 - not used * @returns #CSCF_RETURN_TRUE on success, #CSCF_RETURN_ERROR on error */ int P_enforce_record_routes(struct sip_msg *msg,char *str1, char *str2) { str hdr = {0,0}; str rr_req = {0,0}; struct sip_msg *req = cscf_get_request_from_reply(msg); LOG(L_INFO,"INF:"M_NAME":P_enforce_record_routes(): Enforcing RR in %d reply with the request ones\n", msg->first_line.u.reply.statuscode); if (!req){ LOG(L_ERR,"ERR:"M_NAME":P_enforce_record_routes(): No transactional request found.\n"); return CSCF_RETURN_ERROR; } if(!cscf_del_all_headers(msg, HDR_RECORDROUTE_T)){ LOG(L_ERR,"ERR:"M_NAME":P_enforce_record_routes(): error while deleting headers\n"); return CSCF_RETURN_ERROR; } rr_req = cscf_get_record_routes(req); if(rr_req.len){ hdr.len = pcscf_record_route_mt.len + s_record_route_s.len + rr_req.len+s_record_route_e.len; if(!(hdr.s = pkg_malloc(hdr.len))){ LOG(L_ERR,"ERR:"M_NAME":P_enforce_record_routes(): Unable to allocate memory for hdr\n"); goto out_of_memory; } hdr.len = 0; STR_APPEND(hdr,pcscf_record_route_mt); STR_APPEND(hdr,s_record_route_s); STR_APPEND(hdr,rr_req); STR_APPEND(hdr,s_record_route_e); }else{ LOG(L_ERR,"ERR:"M_NAME":P_enforce_record_routes(): Unable to get record routes - the RR should not be empty...\n"); // still, let it continue, maybe it was empty on purpose //return CSCF_RETURN_ERROR; STR_PKG_DUP(hdr,pcscf_record_route_mt,"pkg"); } if(!cscf_add_header_first(msg,&hdr,HDR_RECORDROUTE_T)){ LOG(L_ERR,"ERR:"M_NAME":P_enforce_record_routes(): Unable to add header\n"); if (hdr.s) pkg_free(hdr.s); return CSCF_RETURN_FALSE; } return CSCF_RETURN_TRUE; out_of_memory: return CSCF_RETURN_ERROR; }
boolean graph_write_dimacs_binary(graph_t *g, char *comment,FILE *fp) { char *buf; char *header=NULL; int headersize=0; int headerlength=0; int i,j; ASSERT((sizeof(setelement)*8)==ELEMENTSIZE); ASSERT(graph_test(g,NULL)); ASSERT(fp!=NULL); buf=malloc(MAX(1024,g->n/8+1)); header=malloc(1024); header[0]=0; headersize=1024; if (comment) { strcpy(buf,"c "); strncat(buf,comment,1000); strcat(buf,"\n"); STR_APPEND(buf); } sprintf(buf,"p edge %d %d\n",g->n,graph_edge_count(g)); STR_APPEND(buf); for (i=0; i < g->n; i++) { if (g->weights[i]!=1) { sprintf(buf,"n %d %d\n",i+1,g->weights[i]); STR_APPEND(buf); } } fprintf(fp,"%d\n",(int)strlen(header)); fprintf(fp,"%s",header); free(header); for (i=0; i < g->n; i++) { memset(buf,0,i/8+1); for (j=0; j<i; j++) { if (GRAPH_IS_EDGE_FAST(g,i,j)) { buf[j/8] |= SET_BIT_MASK(7-j%8); } } fwrite(buf,1,i/8+1,fp); } free(buf); return TRUE; }
int assert_called_identity(struct sip_msg* _m, udomain_t* _d) { int ret=CSCF_RETURN_FALSE; str called_party_id={0,0},x={0,0}; struct sip_msg* req; struct hdr_field *h=0; //get request from reply req = get_request_from_reply(_m); if (!req) { LM_ERR("Unable to get request from reply for REGISTER. No transaction\n"); goto error; } called_party_id = cscf_get_public_identity_from_called_party_id(req, &h); if (!called_party_id.len){ goto error; }else{ LM_DBG("Called Party ID from request: %.*s\n", called_party_id.len, called_party_id.s); x.len = p_asserted_identity_s.len+p_asserted_identity_m.len+called_party_id.len+p_asserted_identity_e.len; x.s = pkg_malloc(x.len); if (!x.s){ LM_ERR("P_assert_called_identity: Error allocating %d bytes\n", x.len); x.len=0; goto error; } x.len=0; STR_APPEND(x,p_asserted_identity_s); STR_APPEND(x,p_asserted_identity_m); STR_APPEND(x,called_party_id); STR_APPEND(x,p_asserted_identity_e); if (cscf_add_header(_m,&x,HDR_OTHER_T)) ret = CSCF_RETURN_TRUE; else goto error; } return ret; error: ret=CSCF_RETURN_FALSE; return ret; }
/* build the extra headers for the OPTIONS reply : containing Content-type and ESQK * @param headers - the resulting string will be stored there * @param d - the user data cell * @return 0 if ok, -1 if error */ int get_options_resp_headers(str * headers, user_d * d){ if(!headers || !d){ LOG(L_ERR, "ERR:"M_NAME":get_options_resp_headers: invalid parameters\n"); return -1; } if(!d->esqk.s || !d->esqk.len){ LOG(L_ERR, "BUG:"M_NAME":get_options_resp_headers: esqk not well set"); return -1; } headers->len = esqk_hdr_s.len + d->esqk.len + esqk_hdr_e.len + content_type_hdr.len + psap_uri_hdr_s.len+d->psap_uri.len+esqk_hdr_e.len+1; headers->s = pkg_malloc(headers->len* sizeof(char)); if(!headers->s){ LOG(L_ERR, "ERR:"M_NAME":get_options_resp_headers: out of pkg memory\n"); return -1; } headers->len = 0; STR_APPEND(*headers, esqk_hdr_s); STR_APPEND(*headers, d->esqk); STR_APPEND(*headers, esqk_hdr_e); STR_APPEND(*headers, psap_uri_hdr_s); STR_APPEND(*headers, d->psap_uri); STR_APPEND(*headers, esqk_hdr_e); if(d->loc && d->locsip_loc) STR_APPEND(*headers, content_type_hdr); headers->s[headers->len] = '\0'; LOG(L_DBG, "DBG:"M_NAME":get_options_resp_headers: headers are: %s\n", headers->s); return 0; }
/** * Replies to a SUBSCRIBE and also adds the need headers. * Path for example. * @param msg - the SIP SUBSCRIBE message * @param code - response code to send * @param text - response phrase to send * @param expires - expiration interval in seconds * @param contact - contact to add to reply * @returns the tmn.r_reply returned value value */ int S_SUBSCRIBE_reply(struct sip_msg *msg, int code, char *text,int *expires,str *contact) { str hdr={0,0}; tmb.t_newtran(msg); if (expires){ hdr.len = expires_hdr1.len+12+expires_hdr1.len; hdr.s = pkg_malloc(hdr.len); if (!hdr.s){ LOG(L_ERR,"ERR:"M_NAME":S_SUBSCRIBE_reply: Error allocating %d bytes.\n", hdr.len); }else{ hdr.len=0; STR_APPEND(hdr,expires_hdr1); sprintf(hdr.s+hdr.len,"%d",*expires); hdr.len += strlen(hdr.s+hdr.len); STR_APPEND(hdr,expires_hdr2); cscf_add_header_rpl(msg,&hdr); pkg_free(hdr.s); } } if (contact){ hdr.len = contact_hdr1.len+contact->len+contact_hdr2.len; hdr.s = pkg_malloc(hdr.len); if (!hdr.s){ LOG(L_ERR,"ERR:"M_NAME":S_SUBSCRIBE_reply: Error allocating %d bytes.\n", hdr.len); }else{ hdr.len=0; STR_APPEND(hdr,contact_hdr1); STR_APPEND(hdr,*contact); STR_APPEND(hdr,contact_hdr2); cscf_add_header_rpl(msg,&hdr); pkg_free(hdr.s); } } return tmb.t_reply(msg,code,text); }
/** * This function sends a bye in the specified dialog * the callback function and parameter are the specified arguments * @param d - the dlg_t to send it on * @param cb -the callback function * @param dir -the direction to identify this s_dialog * @param reason - a reason header to include - see the * @returns 1 on success or 0 on failure */ int send_bye(dlg_t *d,transaction_cb cb,enum s_dialog_direction dir,str reason) { str bye_header_s={0,0}; str reason_header_s={0,0}; if (reason.len!=0) reason_header_s = reason; else reason_header_s = default_reason_s; bye_header_s.len = reason_header_s.len+content_length_s.len; bye_header_s.s = pkg_malloc(bye_header_s.len); if (!bye_header_s.s) { LOG(L_ERR,"ERR:"M_NAME":send_bye(): error allocating %d bytes\n",bye_header_s.len); goto error; } bye_header_s.len=0; STR_APPEND(bye_header_s,reason_header_s); STR_APPEND(bye_header_s,content_length_s); if(d!=NULL) { enum s_dialog_direction *cbp; cbp = shm_malloc(sizeof(enum s_dialog_direction)); if (!cbp){ LOG(L_ERR,"ERR:"M_NAME":send_bye(): error allocating %d bytes\n",sizeof(enum s_dialog_direction)); goto error; } *cbp = dir; dialogb.request_inside(&bye_s, &bye_header_s, 0, d,cb,cbp); if (bye_header_s.s) pkg_free(bye_header_s.s); return 1; } error: if (bye_header_s.s) pkg_free(bye_header_s.s); return 0; }
/** * \brief Store metadata information */ void Storage::storeMetadata(metadata* mdata) { std::stringstream ss; /* Geolocation info */ ss << "\"srcAS\": \"" << mdata->srcAS << "\", "; ss << "\"dstAS\": \"" << mdata->dstAS << "\", "; ss << "\"srcCountry\": \"" << mdata->srcCountry << "\", "; ss << "\"dstCountry\": \"" << mdata->dstCountry << "\", "; ss << "\"srcName\": \"" << mdata->srcName << "\", "; ss << "\"dstName\": \"" << mdata->dstName << "\", "; record += ss.str(); /* Profiles */ STR_APPEND(record, "\"profiles\": ["); if (mdata->channels) { // Get name of root profile void *profile_ptr = NULL; void *prev_profile_ptr = NULL; const char *root_profile_name; profile_ptr = channel_get_profile(mdata->channels[0]); while (profile_ptr != NULL) { prev_profile_ptr = profile_ptr; profile_ptr = profile_get_parent(profile_ptr); } root_profile_name = profile_get_name(prev_profile_ptr); // Process all channels for (int i = 0; mdata->channels[i] != 0; ++i) { if (i > 0) { STR_APPEND(record, ", "); } STR_APPEND(record, "{\"profile\": \""); record += root_profile_name; STR_APPEND(record, "/"); record += profile_get_path(channel_get_profile(mdata->channels[i])); STR_APPEND(record, "\", \"channel\": \""); record += channel_get_name(mdata->channels[i]); STR_APPEND(record, "\"}"); } } record += ']'; }
/** * \brief Read raw data from record */ void Storage::readRawData(uint16_t &length, uint8_t* data_record, uint16_t &offset) { /* Read raw value */ switch (length) { case 1: sprintf(buffer.data(), "%" PRIu16, static_cast<int>(read8(data_record + offset))); break; case 2: sprintf(buffer.data(), "%" PRIu16, ntohs(read16(data_record + offset))); break; case 4: sprintf(buffer.data(), "%" PRIu32, ntohl(read32(data_record + offset))); break; case 8: sprintf(buffer.data(), "%" PRIu64, be64toh(read64(data_record + offset))); break; default: length = this->realLength(length, data_record, offset); if (length == 0) { STR_APPEND(record, "null"); return; } if (length * 2 > buffer.capacity()) { buffer.reserve(length * 2 + 1); } /* Start the string with 0x and print the rest in hexa */ strncpy(buffer.data(), "0x", 3); for (int i = 0; i < length; i++) { sprintf(buffer.data() + i * 2 + 2, "%02x", (data_record + offset)[i]); } } record += '"'; record += buffer.data(); record += '"'; }
static gchar * _memory_properties_to_string (VkMemoryPropertyFlags prop_bits) { GString *s; gboolean first = TRUE; #define STR_APPEND(s,str) \ G_STMT_START { \ if (!first) \ g_string_append (s, "|"); \ g_string_append (s, str); \ first = FALSE; \ } G_STMT_END s = g_string_new (NULL); if (prop_bits & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) { STR_APPEND (s, "device-local"); } if (prop_bits & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { STR_APPEND (s, "host-visible"); if (prop_bits & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) { STR_APPEND (s, "host-coherent"); } else { STR_APPEND (s, "host-incoherent"); } if (prop_bits & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) { STR_APPEND (s, "host-cached"); } else { STR_APPEND (s, "host-uncached"); } } if (prop_bits & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) { STR_APPEND (s, "lazily-allocated"); } return g_string_free (s, FALSE); }
/** * Creates the full reginfo XML. * @param pv - the r_public to create for * @param event_type - event type * @param subsExpires - subscription expiration * @returns the str with the XML content */ str r_get_reginfo_full(void *pv,int event_type,long *subsExpires) { str x={0,0}; str buf,pad; char bufc[MAX_REGINFO_SIZE],padc[MAX_REGINFO_SIZE]; r_public *p=(r_public*)pv,*p2; r_contact *c; r_contact_param *cp; ims_public_identity *pi; int i,j; unsigned int hash; buf.s = bufc; buf.len=0; pad.s = padc; pad.len=0; *subsExpires = r_update_subscription_status(p); STR_APPEND(buf,xml_start); sprintf(pad.s,r_reginfo_s.s,"%d",r_full.len,r_full.s); pad.len = strlen(pad.s); STR_APPEND(buf,pad); if (p->s){ for(i=0;i<p->s->service_profiles_cnt;i++) for(j=0;j<p->s->service_profiles[i].public_identities_cnt;j++){ pi = &(p->s->service_profiles[i].public_identities[j]); if (!pi->barring){ hash = get_aor_hash(pi->public_identity,r_hash_size); if (hash == p->hash) /* because we already have the lock on p->hash */ p2 = get_r_public_nolock(pi->public_identity); else p2 = get_r_public(pi->public_identity); if (p2){ if (p2->reg_state==REGISTERED) sprintf(pad.s,registration_s.s,p2->aor.len,p2->aor.s,p2,r_active.len,r_active.s); else sprintf(pad.s,registration_s.s,p2->aor.len,p2->aor.s,p2,r_terminated.len,r_terminated.s); pad.len = strlen(pad.s); STR_APPEND(buf,pad); c = p2->head; while(c){ if(c->qvalue != -1) { float q = (float)c->qvalue/1000; sprintf(pad.s,contact_s_q.s,c,r_active.len,r_active.s,r_registered.len,r_registered.s,c->expires-time_now, q); } else sprintf(pad.s,contact_s.s,c,r_active.len,r_active.s,r_registered.len,r_registered.s,c->expires-time_now); pad.len = strlen(pad.s); STR_APPEND(buf,pad); STR_APPEND(buf,uri_s); STR_APPEND(buf,c->uri); STR_APPEND(buf,uri_e); for(cp=c->parameters;cp;cp=cp->next){ sprintf(pad.s,unknown_param_s.s,cp->name.len,cp->name.s); pad.len = strlen(pad.s); STR_APPEND(buf,pad); STR_APPEND(buf,cp->value); STR_APPEND(buf,unknown_param_e); } STR_APPEND(buf,contact_e); c = c->next; } STR_APPEND(buf,registration_e); if (p2->hash != p->hash) r_unlock(p2->hash); } } } } STR_APPEND(buf,r_reginfo_e); x.s = pkg_malloc(buf.len+1); if (x.s){ x.len = buf.len; memcpy(x.s,buf.s,buf.len); x.s[x.len]=0; } return x; }
/** * Function that releases a call in early or early200 situation * early200 is when the callee has already sent out 200 but that hasn't * arrived yet to the caller * @param d - p_dialog of the call * @situation - flag to distinguish between two situations * @return 0 on error 1 on success * * \note This function shouldn't be called directly! * use release_call_early or release_call_early200 instead * * \note This function is full of tricks to fake states and * to decieve the transaction module so that it lets us * end a call in weird state * * \note any move in the order of functions to clarify the structure * can lead to a crash in P-CSCF so watch out! */ int release_call_previous(p_dialog *d,enum release_call_situation situation,int reason_code,str reason_text) { struct cell* t; p_dialog *o; enum p_dialog_direction odir; int i; str r; str hdrs={0,0}; char buf[256]; LOG(L_INFO,"DBG:"M_NAME":release_call_previous(): Releasing call <%.*s> DIR[%d].\n", d->call_id.len,d->call_id.s,d->direction); r.len = snprintf(buf,256,"%.*s%d%.*s%.*s%.*s", reason_hdr_s.len,reason_hdr_s.s, reason_code, reason_hdr_1.len,reason_hdr_1.s, reason_text.len,reason_text.s, reason_hdr_e.len,reason_hdr_e.s); r.s = buf; hdrs.len = r.len+content_length_s.len; hdrs.s = pkg_malloc(hdrs.len); if (!hdrs.s){ LOG(L_INFO,"DBG:"M_NAME":release_call_previous(): Error allocating %d bytes.\n",hdrs.len); hdrs.len=0; goto error; } hdrs.len=0; STR_APPEND(hdrs,r); STR_APPEND(hdrs,content_length_s); /* get the dialog in the other direction to see if something going on there and mark as in releasing */ switch (d->direction){ case DLG_MOBILE_ORIGINATING: odir = DLG_MOBILE_TERMINATING; break; case DLG_MOBILE_TERMINATING: odir = DLG_MOBILE_ORIGINATING; break; default: odir = d->direction; } o = get_p_dialog_dir_nolock(d->call_id,odir); if (o && !o->is_releasing) o->is_releasing = 1; d->is_releasing++; if (d->is_releasing>MAX_TIMES_TO_TRY_TO_RELEASE){ LOG(L_ERR,"ERR:"M_NAME":release_call_previous(): had to delete silently dialog %.*s in direction %i\n",d->call_id.len,d->call_id.s,d->direction); del_p_dialog(d); goto error; } alter_dialog_route_set(d->dialog_c,d->direction); d->state=DLG_STATE_TERMINATED_ONE_SIDE; /*this is just a trick to use the same callback function*/ /*trick or treat!*/ d->dialog_c->state=DLG_CONFIRMED; if (situation == RELEASE_CALL_WEIRD){ send_request(method_ACK_s,hdrs,d->dialog_c,0,0); send_request(method_BYE_s,hdrs,d->dialog_c,confirmed_response,d->direction); //d->dialog_c->state=DLG_EARLY; } else {/*(situation == RELEASE_CALL_EARLY)*/ send_request(method_CANCEL_s,hdrs,d->dialog_c,confirmed_response,d->direction); //d->dialog_c->state=DLG_EARLY; } /*i need the cell of the invite!!*/ /*this is very experimental * and very tricky too*/ t=tmb.t_gett(); if (t && t->uas.request) { /*first trick: i really want to get this reply sent even though we are onreply*/ *tmb.route_mode=MODE_ONFAILURE; /*second trick .. i haven't recieve any response from the uac * if i don't do this i get a cancel sent to the S-CSCF .. its not a big deal*/ /*if i cared about sip forking then probably i would not do that and let the * CANCEL go to the S-CSCF (reread specifications needed)*/ for (i=0; i< t->nr_of_outgoings; i++) t->uac[i].last_received=99; /*t->uas.status=100;*/ /*no one cares about this*/ /*now its safe to do this*/ tmb.t_reply(t->uas.request,reason_code,reason_text.s); *tmb.route_mode=MODE_ONREPLY; tmb.t_release(t->uas.request); /*needed because if not i get last message retransmited... * probably there is a more logical way to do this.. but since i really * want this transaction to end .. whats the point?*/ } return 1; error: if (hdrs.s) pkg_free(hdrs.s); return 0; }
/** * Process the 401 response for REGISTER and creates the first Security-Associations. * IPSEc: Only the SA for P_Inc_Req - Incoming Requests is set now as the next REGISTER * could come over that one. * @param rpl - the 401 response * @param str1 - not used * @param str2 - not used * @returns 1 if ok, 0 if not */ int P_security_401(struct sip_msg *rpl,char *str1, char *str2) { struct sip_msg *req; struct hdr_field *hdr; str sec_hdr,sec_srv={0,0}; r_security_type sec_type; char cmd[256]; r_contact *c; r_ipsec *ipsec; float sec_q=-1; str auth; if (!pcscf_use_ipsec &&!pcscf_use_tls) goto ret_false; req = cscf_get_request_from_reply(rpl); if (!req){ LOG(L_ERR,"ERR:"M_NAME":P_security_401: No transactional request found.\n"); goto error; } auth = cscf_get_authenticate(rpl,&hdr); if (!auth.len){ LOG(L_ERR,"ERR:"M_NAME":P_security_401: No WWW-Authenticate header found.\n"); goto ret_false; } sec_hdr = cscf_get_pref_security_header(req,s_security_client, &sec_type,&sec_q); if (!sec_hdr.len) { LOG(L_DBG,"DBG:"M_NAME":P_security_401: No Security-Client header found.\n"); goto ret_false; } LOG(L_INFO,"DBG:"M_NAME":P_security_401: Security-Client header found : <%.*s>.\n", sec_hdr.len, sec_hdr.s); /* save data into registrar */ c = save_contact_security(req, auth, sec_hdr, sec_type, sec_q); if (!c) goto error; switch(sec_type){ case SEC_NONE: break; case SEC_TLS: /* try to add the Security-Server header */ sec_srv.len = s_security_server_s.len+sec_hdr.len+s_security_server_e.len; sec_srv.s = pkg_malloc(sec_srv.len); if (!sec_srv.s){ LOG(L_ERR,"ERR:"M_NAME":P_security_401: Error allocating %d pkg bytes \n",sec_srv.len); goto error; } sec_srv.len=0; STR_APPEND(sec_srv,s_security_server_s); STR_APPEND(sec_srv,sec_hdr); STR_APPEND(sec_srv,s_security_server_e); if (!cscf_add_header(rpl,&sec_srv,HDR_OTHER_T)) { LOG(L_ERR,"ERR:"M_NAME":P_security_401: Error adding header <%.*s> \n",sec_srv.len,sec_srv.s); pkg_free(sec_srv.s); goto error; } break; case SEC_IPSEC: ipsec = c->security_temp->data.ipsec; /* try to add the Security-Server header */ sprintf(cmd,"Security-Server: ipsec-3gpp; ealg=%.*s; alg=%.*s; spi-c=%d; spi-s=%d; port-c=%d; port-s=%d; q=0.1\r\n", ipsec->r_ealg.len,ipsec->r_ealg.s, ipsec->r_alg.len,ipsec->r_alg.s, ipsec->spi_pc,ipsec->spi_ps, pcscf_ipsec_port_c,pcscf_ipsec_port_s); sec_srv.len = strlen(cmd); sec_srv.s = pkg_malloc(sec_srv.len); if (!sec_srv.s){ LOG(L_ERR,"ERR:"M_NAME":P_security_401: Error allocating %d pkg bytes \n",sec_srv.len); goto error; } memcpy(sec_srv.s,cmd,sec_srv.len); if (!cscf_add_header(rpl,&sec_srv,HDR_OTHER_T)) { LOG(L_ERR,"ERR:"M_NAME":P_security_401: Error adding header <%.*s> \n",sec_srv.len,sec_srv.s); pkg_free(sec_srv.s); goto error; } /* run the IPSec script */ /* P_Inc_Req */ sprintf(cmd,"%s %.*s %d %s %d %d %.*s %.*s %.*s %.*s", pcscf_ipsec_P_Inc_Req, c->host.len,c->host.s, ipsec->port_uc, pcscf_ipsec_host, pcscf_ipsec_port_s, ipsec->spi_ps, ipsec->ealg.len,ipsec->ealg.s, ipsec->ck.len,ipsec->ck.s, ipsec->alg.len,ipsec->alg.s, ipsec->ik.len,ipsec->ik.s); r_unlock(c->hash); execute_cmd(cmd); break; } return CSCF_RETURN_TRUE; ret_false: return CSCF_RETURN_FALSE; error: return CSCF_RETURN_ERROR; }
int _gnutls_x509_get_dn(ASN1_TYPE asn1_struct, const char *asn1_rdn_name, gnutls_datum_t * dn) { gnutls_buffer_st out_str; int k2, k1, result; char tmpbuffer1[ASN1_MAX_NAME_SIZE]; char tmpbuffer2[ASN1_MAX_NAME_SIZE]; char tmpbuffer3[ASN1_MAX_NAME_SIZE]; uint8_t value[MAX_STRING_LEN]; gnutls_datum_t td = { NULL, 0 }, tvd = { NULL, 0}; const char *ldap_desc; char oid[MAX_OID_SIZE]; int len; _gnutls_buffer_init(&out_str); k1 = 0; do { k1++; /* create a string like "tbsCertList.issuer.rdnSequence.?1" */ if (asn1_rdn_name[0] != 0) snprintf(tmpbuffer1, sizeof(tmpbuffer1), "%s.?%u", asn1_rdn_name, k1); else snprintf(tmpbuffer1, sizeof(tmpbuffer1), "?%u", k1); len = sizeof(value) - 1; result = asn1_read_value(asn1_struct, tmpbuffer1, value, &len); if (result == ASN1_ELEMENT_NOT_FOUND) { if (k1 == 1) { gnutls_assert(); result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; goto cleanup; } break; } if (result != ASN1_VALUE_NOT_FOUND) { gnutls_assert(); result = _gnutls_asn2err(result); goto cleanup; } k2 = 0; do { /* Move to the attibute type and values */ k2++; if (tmpbuffer1[0] != 0) snprintf(tmpbuffer2, sizeof(tmpbuffer2), "%s.?%u", tmpbuffer1, k2); else snprintf(tmpbuffer2, sizeof(tmpbuffer2), "?%u", k2); /* Try to read the RelativeDistinguishedName attributes. */ len = sizeof(value) - 1; result = asn1_read_value(asn1_struct, tmpbuffer2, value, &len); if (result == ASN1_ELEMENT_NOT_FOUND) break; if (result != ASN1_VALUE_NOT_FOUND) { gnutls_assert(); result = _gnutls_asn2err(result); goto cleanup; } /* Read the OID */ _gnutls_str_cpy(tmpbuffer3, sizeof(tmpbuffer3), tmpbuffer2); _gnutls_str_cat(tmpbuffer3, sizeof(tmpbuffer3), ".type"); len = sizeof(oid) - 1; result = asn1_read_value(asn1_struct, tmpbuffer3, oid, &len); if (result == ASN1_ELEMENT_NOT_FOUND) break; else if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto cleanup; } /* Read the Value */ _gnutls_str_cpy(tmpbuffer3, sizeof(tmpbuffer3), tmpbuffer2); _gnutls_str_cat(tmpbuffer3, sizeof(tmpbuffer3), ".value"); len = 0; result = _gnutls_x509_read_value(asn1_struct, tmpbuffer3, &tvd); if (result < 0) { gnutls_assert(); goto cleanup; } #define STR_APPEND(y) if ((result=_gnutls_buffer_append_str( &out_str, y)) < 0) { \ gnutls_assert(); \ goto cleanup; \ } #define DATA_APPEND(x,y) if ((result=_gnutls_buffer_append_data( &out_str, x,y)) < 0) { \ gnutls_assert(); \ goto cleanup; \ } /* The encodings of adjoining RelativeDistinguishedNames are separated * by a comma character (',' ASCII 44). */ /* Where there is a multi-valued RDN, the outputs from adjoining * AttributeTypeAndValues are separated by a plus ('+' ASCII 43) * character. */ if (k1 != 1) { /* the first time do not append a comma */ if (k2 != 1) { /* adjoining multi-value RDN */ STR_APPEND("+"); } else { STR_APPEND(","); } } ldap_desc = gnutls_x509_dn_oid_name(oid, GNUTLS_X509_DN_OID_RETURN_OID); STR_APPEND(ldap_desc); STR_APPEND("="); result = _gnutls_x509_dn_to_string(oid, tvd.data, tvd.size, &td); if (result < 0) { gnutls_assert(); _gnutls_debug_log ("Cannot parse OID: '%s' with value '%s'\n", oid, _gnutls_bin2hex(tvd.data, tvd.size, tmpbuffer3, sizeof (tmpbuffer3), NULL)); goto cleanup; } DATA_APPEND(td.data, td.size); _gnutls_free_datum(&td); _gnutls_free_datum(&tvd); } while (1); } while (1); result = _gnutls_buffer_to_datum(&out_str, dn, 1); if (result < 0) gnutls_assert(); goto cleanup1; cleanup: _gnutls_buffer_clear(&out_str); cleanup1: _gnutls_free_datum(&td); _gnutls_free_datum(&tvd); return result; }
int I_scscf_select(struct sip_msg* msg, char* str1, char* str2) { str call_id,scscf_name={0,0}; struct sip_msg *req; int result; str hdr={0,0}; //print_scscf_list(L_ERR); call_id = cscf_get_call_id(msg,0); LOG(L_DBG,"DBG:"M_NAME":I_scscf_select(): <%.*s>\n",call_id.len,call_id.s); if (!call_id.len) return CSCF_RETURN_FALSE; scscf_name = take_scscf_entry(call_id); if (!scscf_name.len){ I_scscf_drop(msg,str1,str2); cscf_reply_transactional(msg,600,MSG_600_FORWARDING_FAILED); return CSCF_RETURN_BREAK; } if (msg->first_line.u.request.method.len==8 && strncasecmp(msg->first_line.u.request.method.s,"REGISTER",8)==0) { /* REGISTER fwding */ if (str1&&str1[0]=='0'){ /* first time */ //LOG(L_CRIT,"rewrite uri\n"); if (rewrite_uri(msg, &(scscf_name)) < 0) { LOG(L_ERR,"ERR:"M_NAME":I_UAR_forward: Unable to Rewrite URI\n"); result = CSCF_RETURN_FALSE; }else result = CSCF_RETURN_TRUE; }else{ /* subsequent */ //LOG(L_CRIT,"append branch\n"); req = msg;//cscf_get_request_from_reply(msg); append_branch(req,scscf_name.s,scscf_name.len,0,0,0,0); result = CSCF_RETURN_TRUE; } }else{ /* Another request */ result = CSCF_RETURN_TRUE; hdr.len = route_hdr_s.len+scscf_name.len+route_hdr_e.len; hdr.s = pkg_malloc(hdr.len); if (!hdr.s){ LOG(L_ERR,"ERR:"M_NAME":Mw_REQUEST_forward: Error allocating %d bytes\n", hdr.len); result = CSCF_RETURN_TRUE; } hdr.len=0; STR_APPEND(hdr,route_hdr_s); STR_APPEND(hdr,scscf_name); STR_APPEND(hdr,route_hdr_e); if (!cscf_add_header_first(msg,&hdr,HDR_ROUTE_T)){ pkg_free(hdr.s); result = CSCF_RETURN_TRUE; } if (msg->dst_uri.s) pkg_free(msg->dst_uri.s); STR_PKG_DUP(msg->dst_uri,scscf_name,"pkg"); } if (scscf_name.s) shm_free(scscf_name.s); return result; out_of_memory: if (scscf_name.s) shm_free(scscf_name.s); return CSCF_RETURN_ERROR; }
/** * Force Service routes (upon request) */ int force_service_routes(struct sip_msg* _m, udomain_t* _d) { struct hdr_field *it; int i; str new_route_header; struct lump* lmp = NULL; char * buf; pcontact_t * c = getContactP(_m, _d, PCONTACT_REGISTERED,0 ,0); // char srcip[20]; // str received_host; struct via_body* vb; unsigned short port; unsigned short proto; // Contact not found => not following service-routes if (c == NULL) return -1; /* we need to be sure we have seen all HFs */ parse_headers(_m, HDR_EOH_F, 0); vb = cscf_get_ue_via(_m); port = vb->port?vb->port:5060; proto = vb->proto; /* Save current buffer */ buf = _m->buf; // Delete old Route headers: if (_m->route) { for (it = _m->route; it; it = it->next) { if (it->type == HDR_ROUTE_T) { if ((lmp = del_lump(_m, it->name.s - buf, it->len, HDR_ROUTE_T)) == 0) { LM_ERR("del_lump failed \n"); return -1; } } } } /* Reset dst_uri if previously set either by loose route or manually */ if (_m->dst_uri.s && _m->dst_uri.len) { pkg_free(_m->dst_uri.s); _m->dst_uri.s = NULL; _m->dst_uri.len = 0; } // received_host.len = ip_addr2sbuf(&_m->rcv.src_ip, srcip, sizeof(srcip)); // received_host.s = srcip; /* Lock this record while working with the data: */ ul.lock_udomain(_d, &vb->host, port, proto); if (c->num_service_routes > 0) { /* Create anchor for new Route-Header: */ lmp = anchor_lump(_m, _m->headers->name.s - buf,0,0); if (lmp == 0) { LM_ERR("Failed to get anchor lump\n"); goto error; } /* Calculate the length: */ new_route_header.len = route_start.len + route_end.len + (c->num_service_routes-1) * route_sep.len; for(i=0; i< c->num_service_routes; i++) new_route_header.len+=c->service_routes[i].len; /* Allocate the memory for this new header: */ new_route_header.s = pkg_malloc(new_route_header.len); if (!new_route_header.s) { LM_ERR("Error allocating %d bytes\n", new_route_header.len); goto error; } /* Construct new header */ new_route_header.len = 0; STR_APPEND(new_route_header, route_start); for(i=0; i < c->num_service_routes; i++) { if (i) STR_APPEND(new_route_header, route_sep); STR_APPEND(new_route_header, c->service_routes[i]); } STR_APPEND(new_route_header, route_end); LM_DBG("Setting route header to <%.*s> \n", new_route_header.len, new_route_header.s); if ((lmp = insert_new_lump_after(lmp, new_route_header.s, new_route_header.len, HDR_ROUTE_T)) == 0) { LM_ERR("Error inserting new route set\n"); pkg_free(new_route_header.s); goto error; } LM_DBG("Setting dst_uri to <%.*s> \n", c->service_routes[0].len, c->service_routes[0].s); if (set_dst_uri(_m, &c->service_routes[0]) !=0 ) { LM_ERR("Error setting new dst uri\n"); goto error; } } /* Unlock domain */ ul.unlock_udomain(_d, &vb->host, port, proto); return 1; error: /* Unlock domain */ ul.unlock_udomain(_d, &vb->host, port, proto); return -1; return 1; }
static int stateobj_spy(struct state_object * self, int x, int input, int z, int t) { int old_state = self->current_state; int ans = StateTransition(self, x, input, z, t); int new_state = self->current_state; if (self == SBS_STATE) { STR_APPEND(log, "SBS :"); } else if (self == SCS_STATE) { STR_APPEND(log, "SCS :"); } else if (self == SCSES_STATE) { STR_APPEND(log, "SCSes:"); } else if (self == SCSSR_STATE) { STR_APPEND(log, "SCSsr:"); } else if (self == SDS_REAR_STATE) { STR_APPEND(log, "SDSr :"); } else if (self == SDS_FRONT1_STATE) { STR_APPEND(log, "SDSf1:"); } else if (self == SDS_FRONT2_STATE) { STR_APPEND(log, "SDSf2:"); } else if (self == SDS_FRONT3_STATE) { STR_APPEND(log, "SDSf3:"); } else if (self == SDS_FRONT4_STATE) { STR_APPEND(log, "SDSf4:"); } else if (self == SPS_STATE) { STR_APPEND(log, "SPS :"); } else if (self == FSS_STATE) { STR_APPEND(log, "FSS :"); } else if (self == FCS_STATE) { STR_APPEND(log, "FCS :"); } STR_APPEND(log, "(%d) -- %2d -->(%d)\n", old_state, input, new_state); return ans; }
static int append_elements(ASN1_TYPE asn1_struct, const char *asn1_rdn_name, gnutls_buffer_st *str, int k1, unsigned last) { int k2, result, max_k2; int len; uint8_t value[MAX_STRING_LEN]; char tmpbuffer1[ASN1_MAX_NAME_SIZE]; char tmpbuffer2[ASN1_MAX_NAME_SIZE]; char tmpbuffer3[ASN1_MAX_NAME_SIZE]; const char *ldap_desc; char oid[MAX_OID_SIZE]; gnutls_datum_t td = { NULL, 0 }; gnutls_datum_t tvd = { NULL, 0 }; /* create a string like "tbsCertList.issuer.rdnSequence.?1" */ if (asn1_rdn_name[0] != 0) snprintf(tmpbuffer1, sizeof(tmpbuffer1), "%s.?%u", asn1_rdn_name, k1); else snprintf(tmpbuffer1, sizeof(tmpbuffer1), "?%u", k1); len = sizeof(value) - 1; result = asn1_read_value(asn1_struct, tmpbuffer1, value, &len); if (result != ASN1_VALUE_NOT_FOUND && result != ASN1_SUCCESS) { /* expected */ gnutls_assert(); result = _gnutls_asn2err(result); goto cleanup; } k2 = 0; result = asn1_number_of_elements(asn1_struct, tmpbuffer1, &max_k2); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto cleanup; } do { /* Move to the attibute type and values */ k2++; if (tmpbuffer1[0] != 0) snprintf(tmpbuffer2, sizeof(tmpbuffer2), "%s.?%u", tmpbuffer1, k2); else snprintf(tmpbuffer2, sizeof(tmpbuffer2), "?%u", k2); /* Try to read the RelativeDistinguishedName attributes. */ len = sizeof(value) - 1; result = asn1_read_value(asn1_struct, tmpbuffer2, value, &len); if (result == ASN1_ELEMENT_NOT_FOUND) break; if (result != ASN1_VALUE_NOT_FOUND && result != ASN1_SUCCESS) { /* expected */ gnutls_assert(); result = _gnutls_asn2err(result); goto cleanup; } /* Read the OID */ _gnutls_str_cpy(tmpbuffer3, sizeof(tmpbuffer3), tmpbuffer2); _gnutls_str_cat(tmpbuffer3, sizeof(tmpbuffer3), ".type"); len = sizeof(oid) - 1; result = asn1_read_value(asn1_struct, tmpbuffer3, oid, &len); if (result == ASN1_ELEMENT_NOT_FOUND) break; else if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto cleanup; } /* Read the Value */ _gnutls_str_cpy(tmpbuffer3, sizeof(tmpbuffer3), tmpbuffer2); _gnutls_str_cat(tmpbuffer3, sizeof(tmpbuffer3), ".value"); len = 0; result = _gnutls_x509_read_value(asn1_struct, tmpbuffer3, &tvd); if (result < 0) { gnutls_assert(); goto cleanup; } #define STR_APPEND(y) if ((result=_gnutls_buffer_append_str( str, y)) < 0) { \ gnutls_assert(); \ goto cleanup; \ } #define DATA_APPEND(x,y) if ((result=_gnutls_buffer_append_data( str, x,y)) < 0) { \ gnutls_assert(); \ goto cleanup; \ } /* The encodings of adjoining RelativeDistinguishedNames are separated * by a comma character (',' ASCII 44). */ ldap_desc = gnutls_x509_dn_oid_name(oid, GNUTLS_X509_DN_OID_RETURN_OID); STR_APPEND(ldap_desc); STR_APPEND("="); result = _gnutls_x509_dn_to_string(oid, tvd.data, tvd.size, &td); if (result < 0) { gnutls_assert(); _gnutls_debug_log ("Cannot parse OID: '%s' with value '%s'\n", oid, _gnutls_bin2hex(tvd.data, tvd.size, tmpbuffer3, sizeof (tmpbuffer3), NULL)); goto cleanup; } DATA_APPEND(td.data, td.size); _gnutls_free_datum(&td); _gnutls_free_datum(&tvd); /* Where there is a multi-valued RDN, the outputs from adjoining * AttributeTypeAndValues are separated by a plus ('+' ASCII 43) * character. */ if (k2 < max_k2) { STR_APPEND("+"); } else if (!last) { STR_APPEND(","); } } while (1); result = 0; cleanup: _gnutls_free_datum(&td); _gnutls_free_datum(&tvd); return result; }
/** * \brief Store data record */ void Storage::storeDataRecord(struct metadata *mdata, struct json_conf * config) { const char *element_name = NULL; ELEMENT_TYPE element_type; offset = 0; uint16_t trans_len = 0; const char *trans_str = NULL; record.clear(); STR_APPEND(record, "{\"@type\": \"ipfix.entry\", "); struct ipfix_template *templ = mdata->record.templ; uint8_t *data_record = (uint8_t*) mdata->record.record; /* get all fields */ uint16_t added = 0; for (uint16_t count = 0, index = 0; count < templ->field_count; ++count, ++index) { /* Get Enterprise number and ID */ id = templ->fields[index].ie.id; length = templ->fields[index].ie.length; enterprise = 0; if (id & 0x8000) { id &= 0x7fff; enterprise = templ->fields[++index].enterprise_number; } /* Get element informations */ const ipfix_element_t * element = get_element_by_id(id, enterprise); if (element != NULL) { element_name = element->name; element_type = element->type; } else { // Element not found if (config->ignoreUnknown) { offset += realLength(length, data_record, offset); continue; } element_name = rawName(enterprise, id); element_type = ET_UNASSIGNED; MSG_DEBUG(msg_module, "Unknown element (%s)", element_name); } if (added > 0) { STR_APPEND(record, ", "); } STR_APPEND(record, "\""); record += config->prefix; record += element_name; STR_APPEND(record, "\": "); switch (element_type) { case ET_UNSIGNED_8: case ET_UNSIGNED_16: case ET_UNSIGNED_32: case ET_UNSIGNED_64:{ trans_str = translator.toUnsigned(length, &trans_len, data_record, offset, element, config); record.append(trans_str, trans_len); } break; case ET_SIGNED_8: case ET_SIGNED_16: case ET_SIGNED_32: case ET_SIGNED_64: trans_str = translator.toSigned(length, &trans_len, data_record, offset); record.append(trans_str, trans_len); break; case ET_FLOAT_32: case ET_FLOAT_64: trans_str = translator.toFloat(length, &trans_len, data_record, offset); record.append(trans_str, trans_len); break; case ET_IPV4_ADDRESS: record += '"'; trans_str = translator.formatIPv4(read32(data_record + offset), &trans_len); record.append(trans_str, trans_len); record += '"'; break; case ET_IPV6_ADDRESS: READ_BYTE_ARR(addr6, data_record + offset, IPV6_LEN); record += '"'; record += translator.formatIPv6(addr6); record += '"'; break; case ET_MAC_ADDRESS: READ_BYTE_ARR(addrMac, data_record + offset, MAC_LEN); record += '"'; record += translator.formatMac(addrMac); record += '"'; break; case ET_DATE_TIME_SECONDS: record += translator.formatTimestamp(read32(data_record + offset), t_units::SEC, config); break; case ET_DATE_TIME_MILLISECONDS: record += translator.formatTimestamp(read64(data_record + offset), t_units::MILLISEC, config); break; case ET_DATE_TIME_MICROSECONDS: record += translator.formatTimestamp(read64(data_record + offset), t_units::MICROSEC, config); break; case ET_DATE_TIME_NANOSECONDS: record += translator.formatTimestamp(read64(data_record + offset), t_units::NANOSEC, config); break; case ET_STRING: length = realLength(length, data_record, offset); record += translator.escapeString(length, data_record + offset, config); break; case ET_BOOLEAN: case ET_UNASSIGNED: default: readRawData(length, data_record, offset); break; } offset += length; added++; } /* Store metadata */ if (processMetadata) { STR_APPEND(record, ", \"ipfix.metadata\": {"); storeMetadata(mdata); STR_APPEND(record, "}"); } STR_APPEND(record, "}\n"); sendData(); }
/** * Creates the partial reginfo XML. * @param pv - the r_public to create for * @param pc - the r_contatct to create for * @param event_type - event type * @param subsExpires - subscription expiration * @returns the str with the XML content */ str r_get_reginfo_partial( void *pv,void *pc,int event_type,long *subsExpires) { str x={0,0}; str buf,pad; char bufc[MAX_REGINFO_SIZE],padc[MAX_REGINFO_SIZE]; int expires=-1; r_public *p=(r_public*)pv; r_contact *c=(r_contact*)pc; r_contact_param *cp; str state,event; buf.s = bufc; buf.len=0; pad.s = padc; pad.len=0; *subsExpires = r_update_subscription_status(p); STR_APPEND(buf,xml_start); sprintf(pad.s,r_reginfo_s.s,"%d",r_partial.len,r_partial.s); pad.len = strlen(pad.s); STR_APPEND(buf,pad); if (p){ expires = c->expires-time_now; if (p->head == c && p->tail == c && (event_type==IMS_REGISTRAR_CONTACT_EXPIRED || event_type==IMS_REGISTRAR_CONTACT_DEACTIVATED|| event_type==IMS_REGISTRAR_CONTACT_UNREGISTERED|| event_type==IMS_REGISTRAR_CONTACT_REJECTED) ) sprintf(pad.s,registration_s.s,p->aor.len,p->aor.s,p,r_terminated.len,r_terminated.s); else sprintf(pad.s,registration_s.s,p->aor.len,p->aor.s,p,r_active.len,r_active.s); pad.len = strlen(pad.s); STR_APPEND(buf,pad); if (c){ switch(event_type){ case IMS_REGISTRAR_CONTACT_REGISTERED: state = r_active; event = r_registered; break; case IMS_REGISTRAR_CONTACT_CREATED: state = r_active; event = r_created; break; case IMS_REGISTRAR_CONTACT_REFRESHED: state = r_active; event = r_refreshed; break; case IMS_REGISTRAR_CONTACT_SHORTENED: state = r_active; event = r_shortened; break; case IMS_REGISTRAR_CONTACT_EXPIRED: state = r_terminated; event = r_expired; expires = 0; break; case IMS_REGISTRAR_CONTACT_DEACTIVATED: state = r_terminated; event = r_deactivated; break; case IMS_REGISTRAR_CONTACT_PROBATION: state = r_terminated; event = r_probation; break; case IMS_REGISTRAR_CONTACT_UNREGISTERED: state = r_terminated; event = r_unregistered; expires = 0; break; case IMS_REGISTRAR_CONTACT_REJECTED: state = r_terminated; event = r_rejected; break; default: state = r_active; event = r_registered; } if(c->qvalue != -1) { float q = (float)c->qvalue/1000; sprintf(pad.s,contact_s_q.s,c,r_active.len,r_active.s,r_registered.len,r_registered.s,c->expires-time_now, q); } else sprintf(pad.s,contact_s.s,c,state.len,state.s,event.len,event.s,expires); pad.len = strlen(pad.s); STR_APPEND(buf,pad); STR_APPEND(buf,uri_s); STR_APPEND(buf,c->uri); STR_APPEND(buf,uri_e); for(cp=c->parameters;cp;cp=cp->next){ sprintf(pad.s,unknown_param_s.s,cp->name.len,cp->name.s); pad.len = strlen(pad.s); STR_APPEND(buf,pad); STR_APPEND(buf,cp->value); STR_APPEND(buf,unknown_param_e); } STR_APPEND(buf,contact_e); STR_APPEND(buf,registration_e); } } STR_APPEND(buf,r_reginfo_e); x.s = pkg_malloc(buf.len+1); if (x.s){ x.len = buf.len; memcpy(x.s,buf.s,buf.len); x.s[x.len]=0; } return x; }
static int mod_init(void) { registration_default_algorithm_type = get_algorithm_type(registration_default_algorithm); #ifdef STATISTICS /* register statistics */ if (register_module_stats( exports.name, mod_stats)!=0 ) { LM_ERR("failed to register core statistics\n"); return -1; } if (!register_stats()){ LM_ERR("Unable to register statistics\n"); return -1; } #endif /* check the max_nonce_reuse param */ if (auth_used_vector_timeout < 0) { LM_WARN("bad value for auth_used_vector_timeout parameter (=%d), must be positive. Fixed to 3600\n", auth_used_vector_timeout); auth_used_vector_timeout = 3600; } /* check the max_nonce_reuse param */ if (max_nonce_reuse < 0) { LM_WARN("bad value for max_nonce_reuse parameter (=%d), must be positive. Fixed to 0\n", max_nonce_reuse); max_nonce_reuse = 0; } /* load the CDP API */ if (load_cdp_api(&cdpb) != 0) { LM_ERR("can't load CDP API\n"); return -1; } /* load the TM API */ if (load_tm_api(&tmb) != 0) { LM_ERR("can't load TM API\n"); return -1; } /* Init the authorization data storage */ if (!auth_data_init(auth_data_hash_size)) { LM_ERR("Unable to init auth data\n"); return -1; } /* set default qop */ if (registration_qop.s && registration_qop.len > 0) { registration_qop_str.len = s_qop_s.len + registration_qop.len + s_qop_e.len; registration_qop_str.s = pkg_malloc(registration_qop_str.len); if (!registration_qop_str.s) { LM_ERR("Error allocating %d bytes\n", registration_qop_str.len); registration_qop_str.len = 0; return 0; } registration_qop_str.len = 0; STR_APPEND(registration_qop_str, s_qop_s); memcpy(registration_qop_str.s + registration_qop_str.len, registration_qop.s, registration_qop.len); registration_qop_str.len += registration_qop.len; STR_APPEND(registration_qop_str, s_qop_e); } else { registration_qop_str.len = 0; registration_qop_str.s = 0; } /* Register the auth vector timer */ if (register_timer(reg_await_timer, auth_data, 10) < 0) { LM_ERR("Unable to register auth vector timer\n"); return -1; } return 0; }
/** * Creates a NOTIFY message and sends it * @param n - the r_notification to create the NOTIFY after */ void send_notification(r_notification *n) { str h={0,0}; int k=0; #ifdef SER_MOD_INTERFACE uac_req_t req; #endif LOG(L_DBG,"DBG:"M_NAME":send_notification: NOTIFY about <%.*s>\n",n->uri.len,n->uri.s); //tmb.print_dlg(stdout,n->dialog); h.len = 0; h.len += contact_hdr1.len + n->uri.len + contact_hdr2.len ; if (n->subscription_state.len) h.len += subss_hdr1.len + subss_hdr2.len + n->subscription_state.len; h.len+=event_hdr.len; h.len+=maxfwds_hdr.len; if (n->content_type.len) h.len += ctype_hdr1.len + ctype_hdr2.len + n->content_type.len; h.s = pkg_malloc(h.len); if (!h.s){ LOG(L_ERR,"ERR:"M_NAME":send_notification: Error allocating %d bytes\n",h.len); h.len = 0; } h.len = 0; STR_APPEND(h,contact_hdr1); STR_APPEND(h,n->uri); STR_APPEND(h,contact_hdr2); STR_APPEND(h,event_hdr); STR_APPEND(h,maxfwds_hdr); if (n->subscription_state.len) { STR_APPEND(h,subss_hdr1); STR_APPEND(h,n->subscription_state); STR_APPEND(h,subss_hdr2); } if (n->content_type.len) { STR_APPEND(h,ctype_hdr1); STR_APPEND(h,n->content_type); STR_APPEND(h,ctype_hdr2); } //LOG(L_CRIT,"DLG:%p\n",n->dialog); #ifdef WITH_IMS_PM k = n->is_scscf_dereg; #endif if (n->content.len) { #ifdef SER_MOD_INTERFACE set_uac_req(&req, &method, &h, &(n->content), n->dialog, TMCB_RESPONSE_IN|TMCB_ON_FAILURE|TMCB_LOCAL_COMPLETED, uac_request_cb, (void*)k); tmb.t_request_within(&req); #else tmb.t_request_within(&method, &h, &(n->content), n->dialog, uac_request_cb, (void*)k); #endif } else { #ifdef SER_MOD_INTERFACE set_uac_req(&req, &method, 0, &(n->content), n->dialog, TMCB_RESPONSE_IN|TMCB_ON_FAILURE|TMCB_LOCAL_COMPLETED, uac_request_cb, (void*)k); tmb.t_request_within(&req); #else tmb.t_request_within(&method, &h, 0, n->dialog, uac_request_cb, (void*)k); #endif } if (h.s) pkg_free(h.s); #ifdef WITH_IMS_PM if (n->is_scscf_dereg) IMS_PM_LOG11(UR_AttDeRegCscf,n->dialog->id.call_id,n->dialog->loc_seq.value); #endif }
int r_send_third_party_reg(r_third_party_registration *r, int expires) { str h = {0, 0}; str b = {0, 0}; uac_req_t req; LM_DBG("r_send_third_party_reg: REGISTER to <%.*s>\n", r->req_uri.len, r->req_uri.s); h.len = event_hdr.len + max_fwds_hdr.len; h.len += expires_s.len + 12 + expires_e.len; h.len += contact_s.len + isc_my_uri_sip.len + contact_e.len; if (r->pvni.len) h.len += p_visited_network_id_s.len + p_visited_network_id_e.len + r->pvni.len; if (r->pani.len) h.len += p_access_network_info_s.len + p_access_network_info_e.len + r->pani.len; if (r->cv.len) h.len += p_charging_vector_s.len + p_charging_vector_e.len + r->cv.len; if (r->path.len) h.len += path_s.len + path_e.len + r->path.len + 6/*',' and ';lr' and '<' and '>'*/ + r->from.len /*adding our own address to path*/; h.s = pkg_malloc(h.len); if (!h.s) { LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", h.len); h.len = 0; return 0; } h.len = 0; STR_APPEND(h, event_hdr); STR_APPEND(h, max_fwds_hdr); STR_APPEND(h, expires_s); sprintf(h.s + h.len, "%d", expires); h.len += strlen(h.s + h.len); STR_APPEND(h, expires_e); if (r->path.len) { STR_APPEND(h, path_s); STR_APPEND(h, path_mine_s); STR_APPEND(h, r->from); STR_APPEND(h, path_mine_e); STR_APPEND(h, comma); STR_APPEND(h, r->path); STR_APPEND(h, path_e); } STR_APPEND(h, contact_s); STR_APPEND(h, isc_my_uri_sip); STR_APPEND(h, contact_e); if (r->pvni.len) { STR_APPEND(h, p_visited_network_id_s); STR_APPEND(h, r->pvni); STR_APPEND(h, p_visited_network_id_e); } if (r->pani.len) { STR_APPEND(h, p_access_network_info_s); STR_APPEND(h, r->pani); STR_APPEND(h, p_access_network_info_e); } if (r->cv.len) { STR_APPEND(h, p_charging_vector_s); STR_APPEND(h, r->cv); STR_APPEND(h, p_charging_vector_e); } LM_DBG("SRV INFO:<%.*s>\n", r->service_info.len, r->service_info.s); if (r->service_info.len) { b.len = body_s.len + r->service_info.len + body_e.len; b.s = pkg_malloc(b.len); if (!b.s) { LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", b.len); b.len = 0; return 0; } b.len = 0; STR_APPEND(b, body_s); STR_APPEND(b, r->service_info); STR_APPEND(b, body_e); } set_uac_req(&req, &method, &h, &b, 0, TMCB_RESPONSE_IN | TMCB_ON_FAILURE | TMCB_LOCAL_COMPLETED, r_third_party_reg_response, &(r->req_uri)); if (isc_tmb.t_request(&req, &(r->req_uri), &(r->to), &(r->from), 0) < 0) { LM_ERR("r_send_third_party_reg: Error sending in transaction\n"); goto error; } if (h.s) pkg_free(h.s); return 1; error: if (h.s) pkg_free(h.s); return 0; }
/** * Function that releases a call in early or early200 situation * early200 is when the callee has already sent out 200 but that hasn't * arrived yet to the caller * @param d - p_dialog of the call * @situation - flag to distinguish between two situations * @return 0 on error 1 on success * * \note This function shouldn't be called directly! * use release_call_early or release_call_early200 instead * * \note This function is full of tricks to fake states and * to decieve the transaction module so that it lets us * end a call in weird state * * \note any move in the order of functions to clarify the structure * can lead to a crash in P-CSCF so watch out! */ int release_call_previous(p_dialog *d,enum release_call_situation situation,int reason_code,str reason_text) { struct cell* t; p_dialog *o; enum p_dialog_direction odir; int i; str r; str hdrs= {0,0}; str firstcseq; char buf[256]; if(!d) return 0; LOG(L_INFO,"DBG:"M_NAME":release_call_previous(): Releasing call <%.*s> DIR[%d].\n", d->call_id.len,d->call_id.s,d->direction); r.len = snprintf(buf,256,"%.*s%d%.*s%.*s%.*s", reason_hdr_s.len,reason_hdr_s.s, reason_code, reason_hdr_1.len,reason_hdr_1.s, reason_text.len,reason_text.s, reason_hdr_e.len,reason_hdr_e.s); r.s = buf; hdrs.len = r.len+content_length_s.len; hdrs.s = pkg_malloc(hdrs.len); if (!hdrs.s) { LOG(L_INFO,"DBG:"M_NAME":release_call_previous(): Error allocating %d bytes.\n",hdrs.len); hdrs.len=0; goto error; } hdrs.len=0; STR_APPEND(hdrs,r); STR_APPEND(hdrs,content_length_s); /* get the dialog in the other direction to see if something going on there and mark as in releasing */ switch (d->direction) { case DLG_MOBILE_ORIGINATING: odir = DLG_MOBILE_TERMINATING; break; case DLG_MOBILE_TERMINATING: odir = DLG_MOBILE_ORIGINATING; break; default: odir = d->direction; } time_t time_now=time(0); o = get_p_dialog_dir_nolock(d->call_id,odir); if (o && o->is_releasing==0) { o->is_releasing = 1; // Addition from Alberto Diez the 2nd November 2007 // the idea is to put the other one to expire in TIME_TO_EXPIRE // just in case no reply is received if (o->expires>time_now+TIME_TO_EXPIRE) { o->expires=time_now+TIME_TO_EXPIRE; } } d->is_releasing++; /*The first time i decrease the expire time for the dialog expire , so that i guarantee that * its going to be deleted from the table sometime*/ if (d->expires>time_now+TIME_TO_EXPIRE) { d->expires=time_now+TIME_TO_EXPIRE; } if (d->is_releasing>MAX_TIMES_TO_TRY_TO_RELEASE) { LOG(L_ERR,"ERR:"M_NAME":release_call_previous(): had to delete silently dialog %.*s in direction %i\n",d->call_id.len,d->call_id.s,d->direction); del_p_dialog(d); goto error; } if(alter_dialog_route_set(d->dialog_c,d->direction,situation)<0) { LOG(L_ERR,"ERR:"M_NAME":release_call_previous(): had to delete silently dialog %.*s in direction %i\n",d->call_id.len,d->call_id.s,d->direction); del_p_dialog(d); goto error; } d->state=DLG_STATE_TERMINATED_ONE_SIDE; /*this is just a trick to use the same callback function*/ /*i need the cell of the invite!!*/ /*this is very experimental * and very tricky too*/ //t=tmb.t_gett(); i=0; i=snprintf(buf,256,"%i",d->first_cseq); // i just use buf because its there.. if (i==256) { LOG(L_ERR,"release_call_previous: some client used first CSeq way too big\n"); goto error; } firstcseq.s=pkg_malloc(i+1); // the \0 firstcseq.len=i; sprintf(firstcseq.s,"%i",d->first_cseq); LOG(L_INFO,"CALLED t_lookup_callid with %.*s, %.*s\n",d->call_id.len,d->call_id.s,firstcseq.len,firstcseq.s); if (tmb.t_lookup_callid(&t,d->call_id,firstcseq) < 0) { pkg_free(firstcseq.s); LOG(L_ERR,"release_call_previous: t_lookup_callid failed\n"); goto error; } pkg_free(firstcseq.s); if (t && t!=(void*) -1 && t->uas.request) { if (t->method.len!=6 || t->method.s[0]!='I' || t->method.s[1]!='N' || t->method.s[2]!='V') { //well this is the transaction of a subsequent request within the dialog //and the dialog is not confirmed yet, so its a PRACK or an UPDATE //could also be an options, but the important thing is how am i going to get //the transaction of the invite, that is the one i have to cancel LOG(L_ERR,"this is not my transaction so where am i?\n"); } /*first trick: i really want to get this reply sent even though we are onreply*/ #ifdef SER_MOD_INTERFACE route_type = FAILURE_ROUTE; #else *tmb.route_mode=MODE_ONFAILURE; #endif if (situation == RELEASE_CALL_WEIRD) { /*second trick .. i haven't recieve any response from the uac * if i don't do this i get a cancel sent to the S-CSCF .. its not a big deal*/ /*if i cared about sip forking then probably i would not do that and let the * CANCEL go to the S-CSCF (reread specifications needed)*/ //for (i=0; i< t->nr_of_outgoings; i++) // t->uac[i].last_received=99; /*t->uas.status=100;*/ /*no one cares about this*/ /*now its safe to do this*/ /*trick or treat!*/ for (i=0; i< t->nr_of_outgoings; i++) t->uac[i].last_received=99; t->uas.status=100; d->dialog_c->state=DLG_CONFIRMED; send_request(method_ACK_s,hdrs,d->dialog_c,0,0); send_request(method_BYE_s,hdrs,d->dialog_c,confirmed_response,d->direction); d->dialog_c->state=DLG_EARLY; tmb.t_reply(t->uas.request,reason_code,reason_text.s); *tmb.route_mode=MODE_ONREPLY; t->uas.status=488; tmb.t_release(t->uas.request); /*needed because if not i get last message retransmited... * probably there is a more logical way to do this.. but since i really * want this transaction to end .. whats the point?*/ } else {/*(situation == RELEASE_CALL_EARLY)*/ d->dialog_c->loc_seq.value++; //d->dialog_c->state=DLG_CONFIRMED; //send_request(method_CANCEL_s,hdrs,d->dialog_c,confirmed_response,d->direction); //d->dialog_c->state=DLG_EARLY; tmb.t_reply(t->uas.request,reason_code,reason_text.s); /* for (i=0; i< t->nr_of_outgoings; i++) t->uac[i].last_received=180; */ // t_reply has decided to send a CANCEL already so no big deal! //tmb.cancel_uacs(t,0xFFFF,F_CANCEL_B_FAKE_REPLY); //t->uas.status=488; //tmb.t_release(t->uas.request); // I thought of deleting the dialog here.. but // a good SIP client will respond to the CANCEL with a 487 //del_p_dialog(d); } } if (hdrs.s) pkg_free(hdrs.s); return 1; error: if (hdrs.s) pkg_free(hdrs.s); return 0; }
/** * This functions sends BYE for a confirmed dialog * @param d - the p_dialog to end * @param reason - the Reason: header to include in the messages * @returns 0 on error 1 on success */ int release_call_confirmed(p_dialog *d, int reason_code, str reason_text) { enum p_dialog_direction odir; p_dialog *o; str r; str hdrs={0,0}; char buf[256]; LOG(L_INFO,"DBG:"M_NAME":release_call_confirmed(): Releasing call <%.*s> DIR[%d].\n", d->call_id.len,d->call_id.s,d->direction); r.len = snprintf(buf,256,"%.*s%d%.*s%.*s%.*s", reason_hdr_s.len,reason_hdr_s.s, reason_code, reason_hdr_1.len,reason_hdr_1.s, reason_text.len,reason_text.s, reason_hdr_e.len,reason_hdr_e.s); r.s = buf; hdrs.len = r.len+content_length_s.len; hdrs.s = pkg_malloc(hdrs.len); if (!hdrs.s){ LOG(L_INFO,"DBG:"M_NAME":release_call_confirmed(): Error allocating %d bytes.\n",hdrs.len); hdrs.len=0; goto error; } hdrs.len=0; STR_APPEND(hdrs,r); STR_APPEND(hdrs,content_length_s); /* get the dialog in the other direction to see if something going on there and mark as in releasing */ switch (d->direction){ case DLG_MOBILE_ORIGINATING: odir = DLG_MOBILE_TERMINATING; break; case DLG_MOBILE_TERMINATING: odir = DLG_MOBILE_ORIGINATING; break; default: odir = d->direction; } o = get_p_dialog_dir_nolock(d->call_id,odir); if (o && !o->is_releasing) o->is_releasing = 1; d->is_releasing++; if (d->is_releasing>MAX_TIMES_TO_TRY_TO_RELEASE){ LOG(L_ERR,"ERR:"M_NAME":release_call_confirmed(): had to delete silently dialog %.*s in direction %i\n",d->call_id.len,d->call_id.s,d->direction); del_p_dialog(d); goto error; } if (d->is_releasing==1) { /*Before generating a request, we have to generate * the route_set in the dlg , because the route set * in the dialog is for the UAC everything which was in the * Record-Routes (including local address)*/ alter_dialog_route_set(d->dialog_c,d->direction); /*first generate the bye for called user*/ /*then generate the bye for the calling user*/ send_request(method_BYE_s,hdrs,d->dialog_c,confirmed_response,d->direction); send_request(method_BYE_s,hdrs,d->dialog_s,confirmed_response,d->direction); /*the dialog is droped by the callback-function when receives the two replies */ } if (hdrs.s) pkg_free(hdrs.s); return 1; error: if (hdrs.s) pkg_free(hdrs.s); return 0; }
/** * Send a subscription * @param s - the subsription to send for * @param duration - expires time * @returns true if OK, false if not, error on failure * \todo store the dialog and reSubscribe on the same dialog */ int r_send_subscribe(r_subscription *s,int duration) { str h={0,0}; LOG(L_DBG,"DBG:"M_NAME":r_send_subscribe: SUBSCRIBE to <%.*s>\n", s->req_uri.len,s->req_uri.s); h.len = event_hdr.len+accept_hdr.len+content_len_hdr.len+max_fwds_hdr.len; h.len += expires_s.len + 12 + expires_e.len; h.len += contact_s.len + pcscf_name_str.len + contact_e.len; if (pcscf_path_str.len) h.len += p_asserted_identity_s.len + p_asserted_identity_e.len + pcscf_path_str.len; h.s = pkg_malloc(h.len); if (!h.s){ LOG(L_ERR,"ERR:"M_NAME":r_send_subscribe: Error allocating %d bytes\n",h.len); h.len = 0; return 0; } h.len = 0; STR_APPEND(h,event_hdr); STR_APPEND(h,accept_hdr); STR_APPEND(h,content_len_hdr); STR_APPEND(h,max_fwds_hdr); STR_APPEND(h,expires_s); sprintf(h.s+h.len,"%d",duration); h.len += strlen(h.s+h.len); STR_APPEND(h,expires_e); STR_APPEND(h,contact_s); STR_APPEND(h,pcscf_name_str); STR_APPEND(h,contact_e); if (pcscf_path_str.len) { STR_APPEND(h,p_asserted_identity_s); STR_APPEND(h,pcscf_path_str); STR_APPEND(h,p_asserted_identity_e); } if (!s->dialog){ /* this is the first request in the dialog */ if (tmb.new_dlg_uac(0,0,1,&pcscf_name_str,&s->req_uri,&s->dialog)<0){ LOG(L_ERR,"ERR:"M_NAME":r_send_subscribe: Error creating a dialog for SUBSCRIBE\n"); goto error; } if (dialogb.request_outside(&method, &h, 0, s->dialog, r_subscribe_response, &(s->req_uri)) < 0){ LOG(L_ERR,"ERR:"M_NAME":r_send_subscribe: Error sending initial request in a SUBSCRIBE dialog\n"); goto error; } }else{ /* this is a subsequent subscribe */ if (dialogb.request_inside(&method, &h, 0, s->dialog, r_subscribe_response, &(s->req_uri)) < 0){ LOG(L_ERR,"ERR:"M_NAME":r_send_subscribe: Error sending subsequent request in a SUBSCRIBE dialog\n"); goto error; } } if (h.s) pkg_free(h.s); return 1; error: if (h.s) pkg_free(h.s); return 0; }
/* Parses an X509 DN in the asn1_struct, and puts the output into * the string buf. The output is an LDAP encoded DN. * * asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence". * That is to point in the rndSequence. */ int _gnutls_x509_parse_dn (ASN1_TYPE asn1_struct, const char *asn1_rdn_name, char *buf, size_t * sizeof_buf) { gnutls_string out_str; int k2, k1, result; char tmpbuffer1[MAX_NAME_SIZE]; char tmpbuffer2[MAX_NAME_SIZE]; char tmpbuffer3[MAX_NAME_SIZE]; opaque value[MAX_STRING_LEN], *value2 = NULL; char *escaped = NULL; const char *ldap_desc; char oid[128]; int len, printable; char *string = NULL; size_t sizeof_string, sizeof_escaped; if (sizeof_buf == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } if (buf) buf[0] = 0; else *sizeof_buf = 0; _gnutls_string_init (&out_str, gnutls_malloc, gnutls_realloc, gnutls_free); k1 = 0; do { k1++; /* create a string like "tbsCertList.issuer.rdnSequence.?1" */ if (asn1_rdn_name[0]!=0) snprintf( tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u", asn1_rdn_name, k1); else snprintf( tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1); len = sizeof (value) - 1; result = asn1_read_value (asn1_struct, tmpbuffer1, value, &len); if (result == ASN1_ELEMENT_NOT_FOUND) { break; } if (result != ASN1_VALUE_NOT_FOUND) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } k2 = 0; do { /* Move to the attibute type and values */ k2++; if (tmpbuffer1[0] != 0) snprintf( tmpbuffer2, sizeof (tmpbuffer2), "%s.?%u", tmpbuffer1, k2); else snprintf( tmpbuffer2, sizeof (tmpbuffer2), "?%u", k2); /* Try to read the RelativeDistinguishedName attributes. */ len = sizeof (value) - 1; result = asn1_read_value (asn1_struct, tmpbuffer2, value, &len); if (result == ASN1_ELEMENT_NOT_FOUND) break; if (result != ASN1_VALUE_NOT_FOUND) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } /* Read the OID */ _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2); _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type"); len = sizeof (oid) - 1; result = asn1_read_value (asn1_struct, tmpbuffer3, oid, &len); if (result == ASN1_ELEMENT_NOT_FOUND) break; else if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } /* Read the Value */ _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2); _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".value"); len = 0; result = asn1_read_value (asn1_struct, tmpbuffer3, NULL, &len); value2 = gnutls_malloc (len); if (value2 == NULL) { gnutls_assert (); result = GNUTLS_E_MEMORY_ERROR; goto cleanup; } result = asn1_read_value (asn1_struct, tmpbuffer3, value2, &len); if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } #define STR_APPEND(y) if ((result=_gnutls_string_append_str( &out_str, y)) < 0) { \ gnutls_assert(); \ goto cleanup; \ } /* The encodings of adjoining RelativeDistinguishedNames are separated * by a comma character (',' ASCII 44). */ /* Where there is a multi-valued RDN, the outputs from adjoining * AttributeTypeAndValues are separated by a plus ('+' ASCII 43) * character. */ if (k1 != 1) { /* the first time do not append a comma */ if (k2 != 1) { /* adjoining multi-value RDN */ STR_APPEND ("+"); } else { STR_APPEND (","); } } ldap_desc = oid2ldap_string (oid); printable = _gnutls_x509_oid_data_printable (oid); sizeof_escaped = 2 * len + 1; escaped = gnutls_malloc (sizeof_escaped); if (escaped == NULL) { gnutls_assert (); result = GNUTLS_E_MEMORY_ERROR; goto cleanup; } sizeof_string = 2 * len + 2; /* in case it is not printable */ string = gnutls_malloc (sizeof_string); if (string == NULL) { gnutls_assert (); result = GNUTLS_E_MEMORY_ERROR; goto cleanup; } STR_APPEND (ldap_desc); STR_APPEND ("="); if (printable) result = _gnutls_x509_oid_data2string (oid, value2, len, string, &sizeof_string); else result = _gnutls_x509_data2hex (value2, len, string, &sizeof_string); if (result < 0) { gnutls_assert (); _gnutls_x509_log ("Found OID: '%s' with value '%s'\n", oid, _gnutls_bin2hex (value2, len, escaped, sizeof_escaped)); goto cleanup; } STR_APPEND (str_escape (string, escaped, sizeof_escaped)); gnutls_free (string); string = NULL; gnutls_free (escaped); escaped = NULL; gnutls_free (value2); value2 = NULL; } while (1); } while (1); if (out_str.length >= (unsigned int) *sizeof_buf) { gnutls_assert (); *sizeof_buf = out_str.length + 1; result = GNUTLS_E_SHORT_MEMORY_BUFFER; goto cleanup; } if (buf) { memcpy (buf, out_str.data, out_str.length); buf[out_str.length] = 0; } *sizeof_buf = out_str.length; result = 0; cleanup: gnutls_free (value2); gnutls_free (string); gnutls_free (escaped); _gnutls_string_clear (&out_str); return result; }