/* * Compaction function * 1) Headers of same type will be put together * 2) Header names with compact forms will be transformed to * compact form * 3) Headers which not in whitelist will be removed * 4) Unnecessary sdp body codec attributes lower than 98 removed */ static int mc_compact(struct sip_msg* msg, char* whitelist) { mc_whitelist_p wh_list; struct mc_cmpct_args* args; mc_param_p wh_param = (mc_param_p)whitelist; if (mc_get_whitelist(msg, &wh_param, &wh_list, mnd_hdrs_mask)) { LM_ERR("Cannot get whitelist\n"); return -1; } /* args shall be created only if global contexts do not exist and * tm is not present or tm context is empty */ args=pkg_malloc(sizeof(struct mc_cmpct_args)); if (args==NULL) { LM_ERR("no more pkg mem\n"); goto err00; } args->wh_param = wh_param; args->wh_list = wh_list; SET_GLOBAL_CTX(compact_ctx_pos, (void*)args); /* register stateless callbacks */ if (register_post_raw_processing_cb(wrap_msg_compact, POST_RAW_PROCESSING, 1/*to be freed*/) < 0) { LM_ERR("failed to add raw processing cb\n"); return -1; } if (tm_api.t_gett && msg->flags&FL_TM_CB_REGISTERED) return 1; /*register tm callback if tm api */ if (tm_api.register_tmcb && tm_api.register_tmcb( msg, 0, TMCB_PRE_SEND_BUFFER, wrap_tm_compact, NULL, 0) != 1) { LM_ERR("failed to add tm TMCB_PRE_SEND_BUFFER callback\n"); msg->flags |= FL_TM_CB_REGISTERED; goto err00; } return 1; err00: if (wh_param && wh_param->type == WH_TYPE_PVS) free_whitelist(&wh_list); return -1; }
static int mod_init(void) { LM_INFO("initializing...\n"); /* param handling */ topo_hiding_prefix.len = strlen(topo_hiding_prefix.s); topo_hiding_seed.len = strlen(topo_hiding_seed.s); th_contact_encode_param.len = strlen(th_contact_encode_param.s); if (topo_hiding_ct_params.s) { topo_hiding_ct_params.len = strlen(topo_hiding_ct_params.s); topo_parse_passed_ct_params(&topo_hiding_ct_params); } if (topo_hiding_ct_hdr_params.s) { topo_hiding_ct_hdr_params.len = strlen(topo_hiding_ct_hdr_params.s); topo_parse_passed_hdr_ct_params(&topo_hiding_ct_hdr_params); } /* loading dependencies */ if (load_tm_api(&tm_api)!=0) { LM_ERR("can't load TM API\n"); goto error; } if (load_dlg_api(&dlg_api)!=0) { if (force_dialog) { LM_ERR("cannot force dialog. dialog module not loaded\n"); goto error; } } if (register_pre_raw_processing_cb(topo_callid_pre_raw, PRE_RAW_PROCESSING, 0/*no free*/) < 0) { LM_ERR("failed to initialize pre raw support\n"); return -1; } if (register_post_raw_processing_cb(topo_callid_post_raw, POST_RAW_PROCESSING, 0/*no free*/) < 0) { LM_ERR("failed to initialize post raw support\n"); return -1; } return 0; error: return -1; }
/* * Compression function * 1) Only mandatory headers will be kept * 2) The rest of the headers along with the body * will form the new body which will be use for compression * 3) The Content-Encoding Header will set to gzip, probably * base64 also */ static int mc_compress(struct sip_msg* msg, char* param1, char* param2, char* param3) { int algo=0; int flags=0; int index; pv_value_t value; struct mc_comp_args* args; gparam_p gp_algo = (gparam_p)param1; gparam_p gp_flags = (gparam_p)param2; mc_param_p wh_param = (mc_param_p)param3; mc_whitelist_p hdr2compress_list; /* Default value */ if (gp_algo == NULL) { algo = 0; goto flags; } /* Get algo number */ switch (gp_algo->type) { case GPARAM_TYPE_INT: algo = gp_algo->v.ival; break; case GPARAM_TYPE_PVS: if (pv_get_spec_value(msg, gp_algo->v.pvs, &value) != 0 || !(value.flags&PV_VAL_STR)) { LM_ERR("no valid algo PV value found\n"); return -1; } while(is_space(value.rs.s)) value.rs.s++; if (*value.rs.s >= '0' && *value.rs.s <= '9') algo = *value.rs.s - '0'; else { LM_ERR("algorithm must be a digit\n"); return -1; } } flags: if (gp_flags == NULL) { LM_ERR("mandatory parameter flags not specified.\n"); return -1; } /* Get flags */ switch (gp_flags->type) { case GPARAM_TYPE_INT: flags = gp_flags->v.ival; break; case GPARAM_TYPE_PVS: if (pv_get_spec_value(msg, gp_flags->v.pvs, &value) != 0 || !(value.flags&PV_VAL_STR)) { LM_ERR("no valid flags PV value found\n"); return -1; } if (fixup_compression_flags((void**)&value.rs.s)) { LM_ERR("cannot parse flags\n"); return -1; } flags = ((gparam_p)value.rs.s)->v.ival; pkg_free(value.rs.s); break; } if (!(flags&BODY_COMP_FLG) && !(flags&HDR_COMP_FLG)) { LM_WARN("nothing requested to compress!change flags\n"); return -1; } /* Simulate an whitelist which will contain only the Content-Length header in case BODY_COMP_FLG is set */ if (!(flags&HDR_COMP_FLG)) { hdr2compress_list = pkg_malloc(sizeof(mc_whitelist_t) + HDR_MASK_SIZE); if (!hdr2compress_list) { LM_ERR("no more pkg mem\n"); return -1; } hdr2compress_list->hdr_mask = (unsigned char*)(hdr2compress_list + 1); memset( hdr2compress_list->hdr_mask, 0, HDR_MASK_SIZE); hdr2compress_list->other_hdr = NULL; goto skip_parse; } /* Get headers to compress list */ if (mc_get_whitelist(msg, &wh_param, &hdr2compress_list, NULL)) { LM_ERR("cannot headers to compress list\n"); return -1; } /* Remove mandatory headers if they have been set */ for (index=0; index < veclen(mnd_hdrs, int); index++) { if (hdr2compress_list->hdr_mask[mnd_hdrs[index]/MC_BYTE_SIZE] & (1 << mnd_hdrs[index]%MC_BYTE_SIZE)) { hdr2compress_list->hdr_mask[mnd_hdrs[index]/MC_BYTE_SIZE] ^= 1 << (mnd_hdrs[index]%MC_BYTE_SIZE); } } skip_parse: /* Content Length must be encoded if asked for body to be encoded*/ if (flags&BODY_COMP_FLG) hdr2compress_list->hdr_mask[HDR_CONTENTLENGTH_T/MC_BYTE_SIZE] |= 1 << (HDR_CONTENTLENGTH_T%MC_BYTE_SIZE); args=pkg_malloc(sizeof(struct mc_comp_args)); if (args==NULL) { LM_ERR("no more pkg mem\n"); return -1; } args->hdr2compress_list = hdr2compress_list; args->flags = flags; args->algo = algo; args->wh_param = wh_param; SET_GLOBAL_CTX(compress_ctx_pos, (void*)args); /* register stateless callbacks */ if (register_post_raw_processing_cb(wrap_msg_compress, POST_RAW_PROCESSING, 1/*to be freed*/) < 0) { LM_ERR("failed to add raw processing cb\n"); return -1; } if (tm_api.t_gett && msg->flags&FL_TM_CB_REGISTERED) return 1; /*register tm callback if tm api */ if (tm_api.register_tmcb && tm_api.register_tmcb( msg, 0, TMCB_PRE_SEND_BUFFER, wrap_tm_compress, NULL, 0) != 1) { LM_ERR("failed to add tm TMCB_PRE_SEND_BUFFER callback\n"); msg->flags |= FL_TM_CB_REGISTERED; return -1; } return 1; }