diff --git a/calltable.cpp b/calltable.cpp index 554235d1c..e1c0f201d 100644 --- a/calltable.cpp +++ b/calltable.cpp @@ -237,12 +237,13 @@ extern volatile int terminating; extern sSnifferClientOptions snifferClientOptions; +extern char opt_curl_hook_wav[256]; + extern bool opt_processing_limitations; extern bool opt_processing_limitations_active_calls_cache; extern int opt_processing_limitations_active_calls_cache_type; extern cProcessingLimitations processing_limitations; - sCallField callFields[] = { { cf_callreference, "callreference" }, { cf_callid, "callid" }, @@ -3512,6 +3513,34 @@ Call::convertRawToWav() { if(opt_cachedir[0] != '\0') { Call::_addtocachequeue(tmp); } + + // Here we put our CURL hook + // And use it only if cacheing is turned off + if (opt_curl_hook_wav[0] != '\0' && opt_cachedir[0] == '\0') { + string url; + url.append(opt_curl_hook_wav); + string postData; + postData.append("{ \"voipmonitor\": true"); + postData.append(", \"stereo\":"); + postData.append(useWavMix ? "false" : "true"); + postData.append(", \"wav_file_name_with_path\": \""); + postData.append(out); + postData.append("\", \"call_id\": \""); + postData.append(this->call_id); + postData.append("\" }\n"); + string getParams; // Not used actually + SimpleBuffer responseBuffer; + string error; + s_get_url_response_params curl_params; + + if (!post_url_response((url + getParams).c_str(), &responseBuffer, &postData, &error, &curl_params)) { + // log error message + if(verbosity > 1) syslog(LOG_ERR, "FAIL: Send event to hook[%s] for call_id[%s], error[%s]\n", opt_curl_hook_wav, this->call_id.c_str(), error.c_str()); + } else { + if(verbosity > 1) syslog(LOG_INFO, "SUCCESS: Send event to hook[%s] for call_id[%s], response[%s]\n", opt_curl_hook_wav, this->call_id.c_str(), (char*)responseBuffer); + } + + } return 0; } diff --git a/config/voipmonitor.conf b/config/voipmonitor.conf index 992ae050b..af027a465 100644 --- a/config/voipmonitor.conf +++ b/config/voipmonitor.conf @@ -1559,3 +1559,6 @@ dscp = yes #ss7 = yes #ss7_rudp_port = 7000 + +# Base URL for curl hook +#curl_hook_wav = http://127.0.0.1:8080/you-script-path diff --git a/tools.cpp b/tools.cpp index b210e3d08..034402924 100644 --- a/tools.cpp +++ b/tools.cpp @@ -730,6 +730,86 @@ bool get_url_response(const char *url, SimpleBuffer *response, vector * return(rslt); } +bool post_url_response(const char *url, SimpleBuffer *response, string *postData, string *error, s_get_url_response_params *params) { + if(error) { + *error = ""; + } + bool rslt = false; + CURL *curl = curl_easy_init(); + if(curl) { + struct curl_slist *headers = NULL; + char errorBuffer[1024]; + curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _get_url_response_writer_function); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, response); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false); + curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_0); + curl_easy_setopt(curl, CURLOPT_DNS_USE_GLOBAL_CACHE, 1); + curl_easy_setopt(curl, CURLOPT_DNS_CACHE_TIMEOUT, -1); + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); + if(params && params->timeout_sec) { + curl_easy_setopt(curl, CURLOPT_TIMEOUT, params->timeout_sec); + } + char *urlPathSeparator = (char*)strchr(url + 8, '/'); + string path = urlPathSeparator ? urlPathSeparator : "/"; + string host = urlPathSeparator ? string(url).substr(0, urlPathSeparator - url) : url; + string hostProtPrefix; + size_t posEndHostProtPrefix = host.rfind('/'); + if(posEndHostProtPrefix != string::npos) { + hostProtPrefix = host.substr(0, posEndHostProtPrefix + 1); + host = host.substr(posEndHostProtPrefix + 1); + } + string hostIP = cResolver::resolve_str(host, 0, cResolver::_typeResolve_system_host); + if(!hostIP.empty()) { + headers = curl_slist_append(headers, ("Host: " + host).c_str()); + curl_easy_setopt(curl, CURLOPT_URL, (hostProtPrefix + hostIP + path).c_str()); + } else { + curl_easy_setopt(curl, CURLOPT_URL, url); + } + if(params && params->headers) { + for(unsigned i = 0; i < params->headers->size(); i++) { + headers = curl_slist_append(headers, ((*params->headers)[i][0] + ": " + (*params->headers)[i][1]).c_str()); + } + } + if(headers) { + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + } + extern char opt_curlproxy[256]; + if(opt_curlproxy[0]) { + curl_easy_setopt(curl, CURLOPT_PROXY, opt_curlproxy); + } + if(params && (params->auth_user || params->auth_password)) { + curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(curl, CURLOPT_USERPWD, + ((params->auth_user ? *params->auth_user : "") + + ":" + + (params->auth_password ? *params->auth_password : "")).c_str()); + } + string postFields; + if(postData) { + curl_easy_setopt(curl, CURLOPT_POST, 1); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData->c_str()); + } + if(curl_easy_perform(curl) == CURLE_OK) { + rslt = true; + } else { + if(error) { + *error = errorBuffer; + } + } + if(headers) { + curl_slist_free_all(headers); + } + curl_easy_cleanup(curl); + } else { + if(error) { + *error = "initialize curl failed"; + } + } + return(rslt); +} + /* circular buffer implementation */ CircularBuffer::CircularBuffer(size_t capacity) : beg_index_(0) diff --git a/tools.h b/tools.h index e753efd16..72217279f 100644 --- a/tools.h +++ b/tools.h @@ -364,6 +364,8 @@ struct s_get_url_response_params { }; bool get_url_response(const char *url, SimpleBuffer *response, vector *postData, string *error = NULL, s_get_url_response_params *params = NULL); +bool post_url_response(const char *url, SimpleBuffer *response, string *postData, string *error = NULL, + s_get_url_response_params *params = NULL); long long GetFileSize(std::string filename); time_t GetFileCreateTime(std::string filename); long long GetFileSizeDU(std::string filename, eTypeSpoolFile typeSpoolFile, int spool_index, int dirItemSize = -1); diff --git a/voipmonitor.cpp b/voipmonitor.cpp index 031bccc5e..12e368e9f 100644 --- a/voipmonitor.cpp +++ b/voipmonitor.cpp @@ -1172,6 +1172,10 @@ int opt_process_pcap_type = 0; char opt_pcap_destination[1024]; cConfigItem_net_map::t_net_map opt_anonymize_ip_map; +// SANCOM options BEGIN +char opt_curl_hook_wav[256] = ""; +// SANCOM options END + #include #include @@ -1640,6 +1644,32 @@ void *moving_cache( void */*dummy*/ ) { cachedirtransfered += move_file(src_c, dst_c, true); //TODO: error handling //perror ("The following error occurred"); + + // Here we put our CURL hook + // And use it only if cacheing is turned on + if (opt_curl_hook_wav[0] != '\0' && opt_cachedir[0] != '\0') { + bool useWavMix = opt_saveaudio_wav_mix; + string url; + url.append(opt_curl_hook_wav); + string postData; + postData.append("{ \"voipmonitor\": true"); + postData.append(", \"stereo\":"); + postData.append(useWavMix ? "false" : "true"); + postData.append(", \"wav_file_name_with_path\": \""); + postData.append(dst_c); + postData.append("\" }\n"); + string getParams; // Not used actually + SimpleBuffer responseBuffer; + string error; + s_get_url_response_params curl_params; + + if (!post_url_response((url + getParams).c_str(), &responseBuffer, &postData, &error, &curl_params)) { + // log error message + if(verbosity > 1) syslog(LOG_ERR, "FAIL: Send event to hook[%s], error[%s]\n", opt_curl_hook_wav, error.c_str()); + } else { + if(verbosity > 1) syslog(LOG_INFO, "SUCCESS: Send event to hook[%s], response[%s]\n", opt_curl_hook_wav, (char*)responseBuffer); + } + } } if(terminating_moving_cache) { break; @@ -6926,6 +6956,7 @@ void cConfig::addConfigItems() { expert(); addConfigItem(new FILE_LINE(0) cConfigItem_yesno("saveaudio_dedup_seq", &opt_saveaudio_dedup_seq)); addConfigItem(new FILE_LINE(42230) cConfigItem_yesno("plcdisable", &opt_disableplc)); + addConfigItem(new FILE_LINE(1162) cConfigItem_string("curl_hook_wav", opt_curl_hook_wav, sizeof(opt_curl_hook_wav))); setDisableIfEnd(); group("data spool directory cleaning"); setDisableIfBegin("sniffer_mode=" + snifferMode_sender_str); @@ -11786,6 +11817,10 @@ int eval_config(string inistr) { opt_abort_if_rss_gt_gb = atoi(value); } + if((value = ini.GetValue("general", "curl_hook_wav", NULL))) { + strcpy_null_term(opt_curl_hook_wav, value); + } + /* packetbuffer default configuration