TT#26756 clean up CLI code using streambuf

Change-Id: I0e6c264d5cbd569fb35fab3ad2b0a4f6413949b0
changes/44/17744/5
Richard Fuchs 7 years ago
parent d10952a029
commit 2eb01695bb

@ -19,6 +19,8 @@
#include "control_ng.h" #include "control_ng.h"
#include "media_socket.h" #include "media_socket.h"
#include "cdr.h" #include "cdr.h"
#include "streambuf.h"
#include "tcp_listener.h"
#include "rtpengine_config.h" #include "rtpengine_config.h"
@ -89,8 +91,7 @@ static void destroy_keyspace_foreign_calls(struct callmaster *m, unsigned int ui
destroy_own_foreign_calls(m, CT_FOREIGN_CALL, uint_keyspace_db); destroy_own_foreign_calls(m, CT_FOREIGN_CALL, uint_keyspace_db);
} }
static void cli_incoming_list_totals(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { static void cli_incoming_list_totals(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) {
int printlen=0;
struct timeval avg, calls_dur_iv; struct timeval avg, calls_dur_iv;
u_int64_t num_sessions, min_sess_iv, max_sess_iv; u_int64_t num_sessions, min_sess_iv, max_sess_iv;
struct request_time offer_iv, answer_iv, delete_iv; struct request_time offer_iv, answer_iv, delete_iv;
@ -100,34 +101,20 @@ static void cli_incoming_list_totals(char* buffer, int len, struct callmaster* m
num_sessions = m->totalstats.total_managed_sess; num_sessions = m->totalstats.total_managed_sess;
mutex_unlock(&m->totalstats.total_average_lock); mutex_unlock(&m->totalstats.total_average_lock);
printlen = snprintf(replybuffer,(outbufend-replybuffer), "\nTotal statistics (does not include current running sessions):\n\n"); streambuf_printf(replybuffer, "\nTotal statistics (does not include current running sessions):\n\n");
ADJUSTLEN(printlen,outbufend,replybuffer); streambuf_printf(replybuffer, " Uptime of rtpengine :%llu seconds\n", (unsigned long long)time(NULL)-m->totalstats.started);
printlen = snprintf(replybuffer,(outbufend-replybuffer), " Uptime of rtpengine :%llu seconds\n", (unsigned long long)time(NULL)-m->totalstats.started); streambuf_printf(replybuffer, " Total managed sessions :"UINT64F"\n", num_sessions);
ADJUSTLEN(printlen,outbufend,replybuffer); streambuf_printf(replybuffer, " Total rejected sessions :"UINT64F"\n", atomic64_get(&m->totalstats.total_rejected_sess));
printlen = snprintf(replybuffer,(outbufend-replybuffer), " Total managed sessions :"UINT64F"\n", num_sessions); streambuf_printf(replybuffer, " Total timed-out sessions via TIMEOUT :"UINT64F"\n",atomic64_get(&m->totalstats.total_timeout_sess));
ADJUSTLEN(printlen,outbufend,replybuffer); streambuf_printf(replybuffer, " Total timed-out sessions via SILENT_TIMEOUT :"UINT64F"\n",atomic64_get(&m->totalstats.total_silent_timeout_sess));
printlen = snprintf(replybuffer,(outbufend-replybuffer), " Total rejected sessions :"UINT64F"\n", atomic64_get(&m->totalstats.total_rejected_sess)); streambuf_printf(replybuffer, " Total timed-out sessions via FINAL_TIMEOUT :"UINT64F"\n",atomic64_get(&m->totalstats.total_final_timeout_sess));
ADJUSTLEN(printlen,outbufend,replybuffer); streambuf_printf(replybuffer, " Total regular terminated sessions :"UINT64F"\n",atomic64_get(&m->totalstats.total_regular_term_sess));
printlen = snprintf(replybuffer,(outbufend-replybuffer), " Total timed-out sessions via TIMEOUT :"UINT64F"\n",atomic64_get(&m->totalstats.total_timeout_sess)); streambuf_printf(replybuffer, " Total forced terminated sessions :"UINT64F"\n",atomic64_get(&m->totalstats.total_forced_term_sess));
ADJUSTLEN(printlen,outbufend,replybuffer); streambuf_printf(replybuffer, " Total relayed packets :"UINT64F"\n",atomic64_get(&m->totalstats.total_relayed_packets));
printlen = snprintf(replybuffer,(outbufend-replybuffer), " Total timed-out sessions via SILENT_TIMEOUT :"UINT64F"\n",atomic64_get(&m->totalstats.total_silent_timeout_sess)); streambuf_printf(replybuffer, " Total relayed packet errors :"UINT64F"\n",atomic64_get(&m->totalstats.total_relayed_errors));
ADJUSTLEN(printlen,outbufend,replybuffer); streambuf_printf(replybuffer, " Total number of streams with no relayed packets :"UINT64F"\n", atomic64_get(&m->totalstats.total_nopacket_relayed_sess));
printlen = snprintf(replybuffer,(outbufend-replybuffer), " Total timed-out sessions via FINAL_TIMEOUT :"UINT64F"\n",atomic64_get(&m->totalstats.total_final_timeout_sess)); streambuf_printf(replybuffer, " Total number of 1-way streams :"UINT64F"\n",atomic64_get(&m->totalstats.total_oneway_stream_sess));
ADJUSTLEN(printlen,outbufend,replybuffer); streambuf_printf(replybuffer, " Average call duration :%ld.%06ld\n\n",avg.tv_sec,avg.tv_usec);
printlen = snprintf(replybuffer,(outbufend-replybuffer), " Total regular terminated sessions :"UINT64F"\n",atomic64_get(&m->totalstats.total_regular_term_sess));
ADJUSTLEN(printlen,outbufend,replybuffer);
printlen = snprintf(replybuffer,(outbufend-replybuffer), " Total forced terminated sessions :"UINT64F"\n",atomic64_get(&m->totalstats.total_forced_term_sess));
ADJUSTLEN(printlen,outbufend,replybuffer);
printlen = snprintf(replybuffer,(outbufend-replybuffer), " Total relayed packets :"UINT64F"\n",atomic64_get(&m->totalstats.total_relayed_packets));
ADJUSTLEN(printlen,outbufend,replybuffer);
printlen = snprintf(replybuffer,(outbufend-replybuffer), " Total relayed packet errors :"UINT64F"\n",atomic64_get(&m->totalstats.total_relayed_errors));
ADJUSTLEN(printlen,outbufend,replybuffer);
printlen = snprintf(replybuffer,(outbufend-replybuffer), " Total number of streams with no relayed packets :"UINT64F"\n", atomic64_get(&m->totalstats.total_nopacket_relayed_sess));
ADJUSTLEN(printlen,outbufend,replybuffer);
printlen = snprintf(replybuffer,(outbufend-replybuffer), " Total number of 1-way streams :"UINT64F"\n",atomic64_get(&m->totalstats.total_oneway_stream_sess));
ADJUSTLEN(printlen,outbufend,replybuffer);
printlen = snprintf(replybuffer,(outbufend-replybuffer), " Average call duration :%ld.%06ld\n\n",avg.tv_sec,avg.tv_usec);
ADJUSTLEN(printlen,outbufend,replybuffer);
mutex_lock(&m->totalstats_lastinterval_lock); mutex_lock(&m->totalstats_lastinterval_lock);
calls_dur_iv = m->totalstats_lastinterval.total_calls_duration_interval; calls_dur_iv = m->totalstats_lastinterval.total_calls_duration_interval;
@ -143,49 +130,38 @@ static void cli_incoming_list_totals(char* buffer, int len, struct callmaster* m
timeval_divide(&answer_iv.time_avg, &answer_iv.time_avg, answer_iv.count); timeval_divide(&answer_iv.time_avg, &answer_iv.time_avg, answer_iv.count);
timeval_divide(&delete_iv.time_avg, &delete_iv.time_avg, delete_iv.count); timeval_divide(&delete_iv.time_avg, &delete_iv.time_avg, delete_iv.count);
printlen = snprintf(replybuffer,(outbufend-replybuffer), "\nGraphite interval statistics (last reported values to graphite):\n"); streambuf_printf(replybuffer, "\nGraphite interval statistics (last reported values to graphite):\n");
ADJUSTLEN(printlen,outbufend,replybuffer); streambuf_printf(replybuffer, " Total calls duration :%ld.%06ld\n\n",calls_dur_iv.tv_sec,calls_dur_iv.tv_usec);
printlen = snprintf(replybuffer,(outbufend-replybuffer), " Total calls duration :%ld.%06ld\n\n",calls_dur_iv.tv_sec,calls_dur_iv.tv_usec); streambuf_printf(replybuffer, " Min managed sessions :"UINT64F"\n", min_sess_iv);
ADJUSTLEN(printlen,outbufend,replybuffer); streambuf_printf(replybuffer, " Max managed sessions :"UINT64F"\n", max_sess_iv);
printlen = snprintf(replybuffer,(outbufend-replybuffer), " Min managed sessions :"UINT64F"\n", min_sess_iv); streambuf_printf(replybuffer, " Min/Max/Avg offer processing delay :%llu.%06llu/%llu.%06llu/%llu.%06llu sec\n",
ADJUSTLEN(printlen,outbufend,replybuffer);
printlen = snprintf(replybuffer,(outbufend-replybuffer), " Max managed sessions :"UINT64F"\n", max_sess_iv);
ADJUSTLEN(printlen,outbufend,replybuffer);
printlen = snprintf(replybuffer,(outbufend-replybuffer), " Min/Max/Avg offer processing delay :%llu.%06llu/%llu.%06llu/%llu.%06llu sec\n",
(unsigned long long)offer_iv.time_min.tv_sec,(unsigned long long)offer_iv.time_min.tv_usec, (unsigned long long)offer_iv.time_min.tv_sec,(unsigned long long)offer_iv.time_min.tv_usec,
(unsigned long long)offer_iv.time_max.tv_sec,(unsigned long long)offer_iv.time_max.tv_usec, (unsigned long long)offer_iv.time_max.tv_sec,(unsigned long long)offer_iv.time_max.tv_usec,
(unsigned long long)offer_iv.time_avg.tv_sec,(unsigned long long)offer_iv.time_avg.tv_usec); (unsigned long long)offer_iv.time_avg.tv_sec,(unsigned long long)offer_iv.time_avg.tv_usec);
ADJUSTLEN(printlen,outbufend,replybuffer); streambuf_printf(replybuffer, " Min/Max/Avg answer processing delay :%llu.%06llu/%llu.%06llu/%llu.%06llu sec\n",
printlen = snprintf(replybuffer,(outbufend-replybuffer), " Min/Max/Avg answer processing delay :%llu.%06llu/%llu.%06llu/%llu.%06llu sec\n",
(unsigned long long)answer_iv.time_min.tv_sec,(unsigned long long)answer_iv.time_min.tv_usec, (unsigned long long)answer_iv.time_min.tv_sec,(unsigned long long)answer_iv.time_min.tv_usec,
(unsigned long long)answer_iv.time_max.tv_sec,(unsigned long long)answer_iv.time_max.tv_usec, (unsigned long long)answer_iv.time_max.tv_sec,(unsigned long long)answer_iv.time_max.tv_usec,
(unsigned long long)answer_iv.time_avg.tv_sec,(unsigned long long)answer_iv.time_avg.tv_usec); (unsigned long long)answer_iv.time_avg.tv_sec,(unsigned long long)answer_iv.time_avg.tv_usec);
ADJUSTLEN(printlen,outbufend,replybuffer); streambuf_printf(replybuffer, " Min/Max/Avg delete processing delay :%llu.%06llu/%llu.%06llu/%llu.%06llu sec\n",
printlen = snprintf(replybuffer,(outbufend-replybuffer), " Min/Max/Avg delete processing delay :%llu.%06llu/%llu.%06llu/%llu.%06llu sec\n",
(unsigned long long)delete_iv.time_min.tv_sec,(unsigned long long)delete_iv.time_min.tv_usec, (unsigned long long)delete_iv.time_min.tv_sec,(unsigned long long)delete_iv.time_min.tv_usec,
(unsigned long long)delete_iv.time_max.tv_sec,(unsigned long long)delete_iv.time_max.tv_usec, (unsigned long long)delete_iv.time_max.tv_sec,(unsigned long long)delete_iv.time_max.tv_usec,
(unsigned long long)delete_iv.time_avg.tv_sec,(unsigned long long)delete_iv.time_avg.tv_usec); (unsigned long long)delete_iv.time_avg.tv_sec,(unsigned long long)delete_iv.time_avg.tv_usec);
ADJUSTLEN(printlen,outbufend,replybuffer);
printlen = snprintf(replybuffer,(outbufend-replybuffer), "\n\n"); streambuf_printf(replybuffer, "\n\n");
ADJUSTLEN(printlen,outbufend,replybuffer);
printlen = snprintf(replybuffer,(outbufend-replybuffer), "Control statistics:\n\n"); streambuf_printf(replybuffer, "Control statistics:\n\n");
ADJUSTLEN(printlen,outbufend,replybuffer); streambuf_printf(replybuffer, " %20s | %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s \n",
printlen = snprintf(replybuffer,(outbufend-replybuffer), " %20s | %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s \n",
"Proxy", "Offer", "Answer", "Delete", "Ping", "List", "Query", "StartRec", "StopRec", "Errors"); "Proxy", "Offer", "Answer", "Delete", "Ping", "List", "Query", "StartRec", "StopRec", "Errors");
ADJUSTLEN(printlen,outbufend,replybuffer);
mutex_lock(&m->cngs_lock); mutex_lock(&m->cngs_lock);
GList *list = g_hash_table_get_values(m->cngs_hash); GList *list = g_hash_table_get_values(m->cngs_hash);
if (!list) { if (!list) {
printlen = snprintf(replybuffer,(outbufend-replybuffer), "\n No proxies have yet tried to send data."); streambuf_printf(replybuffer, "\n No proxies have yet tried to send data.");
ADJUSTLEN(printlen,outbufend,replybuffer);
} }
for (GList *l = list; l; l = l->next) { for (GList *l = list; l; l = l->next) {
struct control_ng_stats* cur = l->data; struct control_ng_stats* cur = l->data;
printlen = snprintf(replybuffer,(outbufend-replybuffer), " %20s | %10u | %10u | %10u | %10u | %10u | %10u | %10u | %10u | %10u \n", streambuf_printf(replybuffer, " %20s | %10u | %10u | %10u | %10u | %10u | %10u | %10u | %10u | %10u \n",
sockaddr_print_buf(&cur->proxy), sockaddr_print_buf(&cur->proxy),
cur->offer, cur->offer,
cur->answer, cur->answer,
@ -196,65 +172,51 @@ static void cli_incoming_list_totals(char* buffer, int len, struct callmaster* m
cur->start_recording, cur->start_recording,
cur->stop_recording, cur->stop_recording,
cur->errors); cur->errors);
ADJUSTLEN(printlen,outbufend,replybuffer);
} }
printlen = snprintf(replybuffer,(outbufend-replybuffer), "\n\n"); streambuf_printf(replybuffer, "\n\n");
ADJUSTLEN(printlen,outbufend,replybuffer);
mutex_unlock(&m->cngs_lock); mutex_unlock(&m->cngs_lock);
g_list_free(list); g_list_free(list);
} }
static void cli_incoming_list_maxsessions(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { static void cli_incoming_list_maxsessions(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) {
int printlen=0;
/* don't lock anything while reading the value */ /* don't lock anything while reading the value */
printlen = snprintf(replybuffer,(outbufend-replybuffer), "Maximum sessions configured on rtpengine: %d\n", m->conf.max_sessions); streambuf_printf(replybuffer, "Maximum sessions configured on rtpengine: %d\n", m->conf.max_sessions);
ADJUSTLEN(printlen,outbufend,replybuffer);
return ; return ;
} }
static void cli_incoming_list_maxopenfiles(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { static void cli_incoming_list_maxopenfiles(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) {
int printlen=0;
struct rlimit rlim; struct rlimit rlim;
pid_t pid = getpid(); pid_t pid = getpid();
if (getrlimit(RLIMIT_NOFILE, &rlim) == -1) { if (getrlimit(RLIMIT_NOFILE, &rlim) == -1) {
printlen = snprintf(replybuffer,(outbufend-replybuffer), "Fail getting rtpengine configured limits; cat /proc/%u/limits\n", pid); streambuf_printf(replybuffer, "Fail getting rtpengine configured limits; cat /proc/%u/limits\n", pid);
ADJUSTLEN(printlen,outbufend,replybuffer);
return ; return ;
} }
if (rlim.rlim_cur == RLIM_INFINITY) { if (rlim.rlim_cur == RLIM_INFINITY) {
printlen = snprintf(replybuffer,(outbufend-replybuffer), "Maximum open-files configured on rtpengine: infinite; cat /proc/%u/limits\n", pid); streambuf_printf(replybuffer, "Maximum open-files configured on rtpengine: infinite; cat /proc/%u/limits\n", pid);
ADJUSTLEN(printlen,outbufend,replybuffer);
} else { } else {
printlen = snprintf(replybuffer,(outbufend-replybuffer), "Maximum open-files configured on rtpengine: %lld; cat /proc/%u/limits\n", (long long) rlim.rlim_cur, pid); streambuf_printf(replybuffer, "Maximum open-files configured on rtpengine: %lld; cat /proc/%u/limits\n", (long long) rlim.rlim_cur, pid);
ADJUSTLEN(printlen,outbufend,replybuffer);
} }
return ; return ;
} }
static void cli_incoming_list_timeout(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { static void cli_incoming_list_timeout(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) {
int printlen=0;
rwlock_lock_r(&m->conf.config_lock); rwlock_lock_r(&m->conf.config_lock);
/* don't lock anything while reading the value */ /* don't lock anything while reading the value */
printlen = snprintf(replybuffer,(outbufend-replybuffer), "TIMEOUT=%u\n", m->conf.timeout); streambuf_printf(replybuffer, "TIMEOUT=%u\n", m->conf.timeout);
ADJUSTLEN(printlen,outbufend,replybuffer); streambuf_printf(replybuffer, "SILENT_TIMEOUT=%u\n", m->conf.silent_timeout);
printlen = snprintf(replybuffer,(outbufend-replybuffer), "SILENT_TIMEOUT=%u\n", m->conf.silent_timeout); streambuf_printf(replybuffer, "FINAL_TIMEOUT=%u\n", m->conf.final_timeout);
ADJUSTLEN(printlen,outbufend,replybuffer);
printlen = snprintf(replybuffer,(outbufend-replybuffer), "FINAL_TIMEOUT=%u\n", m->conf.final_timeout);
ADJUSTLEN(printlen,outbufend,replybuffer);
rwlock_unlock_r(&m->conf.config_lock); rwlock_unlock_r(&m->conf.config_lock);
return ; return ;
} }
static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) {
str callid; str callid;
struct call* c=0; struct call* c=0;
struct call_monologue *ml; struct call_monologue *ml;
@ -262,14 +224,12 @@ static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m
struct packet_stream *ps; struct packet_stream *ps;
GList *l; GList *l;
GList *k, *o; GList *k, *o;
int printlen=0;
struct timeval tim_result_duration; struct timeval tim_result_duration;
struct timeval now; struct timeval now;
char * local_addr; char * local_addr;
if (len<=1) { if (len<=1) {
printlen = snprintf(replybuffer,(outbufend-replybuffer), "%s\n", "More parameters required."); streambuf_printf(replybuffer, "%s\n", "More parameters required.");
ADJUSTLEN(printlen,outbufend,replybuffer);
return; return;
} }
// ++buffer; --len; // one space // ++buffer; --len; // one space
@ -278,14 +238,12 @@ static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m
c = call_get(&callid, m); c = call_get(&callid, m);
if (!c) { if (!c) {
printlen = snprintf(replybuffer,(outbufend-replybuffer), "\nCall Id not found (%s).\n\n",callid.s); streambuf_printf(replybuffer, "\nCall Id not found (%s).\n\n",callid.s);
ADJUSTLEN(printlen,outbufend,replybuffer);
return; return;
} }
printlen = snprintf (replybuffer,(outbufend-replybuffer), "\ncallid: %60s | deletionmark:%4s | created:%12i | proxy:%s | tos:%u | last_signal:%llu | redis_keyspace:%i | foreign:%s\n\n", streambuf_printf(replybuffer, "\ncallid: %60s | deletionmark:%4s | created:%12i | proxy:%s | tos:%u | last_signal:%llu | redis_keyspace:%i | foreign:%s\n\n",
c->callid.s , c->ml_deleted?"yes":"no", (int)c->created.tv_sec, c->created_from, (unsigned int)c->tos, (unsigned long long)c->last_signal, c->redis_hosted_db, IS_FOREIGN_CALL(c)?"yes":"no"); c->callid.s , c->ml_deleted?"yes":"no", (int)c->created.tv_sec, c->created_from, (unsigned int)c->tos, (unsigned long long)c->last_signal, c->redis_hosted_db, IS_FOREIGN_CALL(c)?"yes":"no");
ADJUSTLEN(printlen,outbufend,replybuffer);
for (l = c->monologues.head; l; l = l->next) { for (l = c->monologues.head; l; l = l->next) {
ml = l->data; ml = l->data;
@ -295,14 +253,13 @@ static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m
now = ml->terminated; now = ml->terminated;
} }
timeval_subtract(&tim_result_duration,&now,&ml->started); timeval_subtract(&tim_result_duration,&now,&ml->started);
printlen = snprintf(replybuffer,(outbufend-replybuffer), "--- Tag '"STR_FORMAT"' type: %s, callduration " streambuf_printf(replybuffer, "--- Tag '"STR_FORMAT"' type: %s, callduration "
"%ld.%06ld , in dialogue with '"STR_FORMAT"'\n", "%ld.%06ld , in dialogue with '"STR_FORMAT"'\n",
STR_FMT(&ml->tag), get_tag_type_text(ml->tagtype), STR_FMT(&ml->tag), get_tag_type_text(ml->tagtype),
tim_result_duration.tv_sec, tim_result_duration.tv_sec,
tim_result_duration.tv_usec, tim_result_duration.tv_usec,
ml->active_dialogue ? ml->active_dialogue->tag.len : 6, ml->active_dialogue ? ml->active_dialogue->tag.len : 6,
ml->active_dialogue ? ml->active_dialogue->tag.s : "(none)"); ml->active_dialogue ? ml->active_dialogue->tag.s : "(none)");
ADJUSTLEN(printlen,outbufend,replybuffer);
for (k = ml->medias.head; k; k = k->next) { for (k = ml->medias.head; k; k = k->next) {
md = k->data; md = k->data;
@ -316,7 +273,7 @@ static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m
local_addr = ps->selected_sfd ? sockaddr_print_buf(&ps->selected_sfd->socket.local.address) : "0.0.0.0"; local_addr = ps->selected_sfd ? sockaddr_print_buf(&ps->selected_sfd->socket.local.address) : "0.0.0.0";
#if (RE_HAS_MEASUREDELAY) #if (RE_HAS_MEASUREDELAY)
if (!PS_ISSET(ps, RTP) && PS_ISSET(ps, RTCP)) { if (!PS_ISSET(ps, RTP) && PS_ISSET(ps, RTCP)) {
printlen = snprintf(replybuffer,(outbufend-replybuffer), "------ Media #%u, %15s:%-5hu <> %15s:%-5hu%s, " streambuf_printf(replybuffer, "------ Media #%u, %15s:%-5hu <> %15s:%-5hu%s, "
""UINT64F" p, "UINT64F" b, "UINT64F" e, "UINT64F" last_packet\n", ""UINT64F" p, "UINT64F" b, "UINT64F" e, "UINT64F" last_packet\n",
md->index, md->index,
local_addr, (unsigned int) (ps->sfd ? ps->sfd->fd.localport : 0), local_addr, (unsigned int) (ps->sfd ? ps->sfd->fd.localport : 0),
@ -327,7 +284,7 @@ static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m
atomic64_get(&ps->stats.errors), atomic64_get(&ps->stats.errors),
atomic64_get(&ps->last_packet)); atomic64_get(&ps->last_packet));
} else { } else {
printlen = snprintf(replybuffer,(outbufend-replybuffer), "------ Media #%u, %15s:%-5hu <> %15s:%-5hu%s, " streambuf_printf(replybuffer, "------ Media #%u, %15s:%-5hu <> %15s:%-5hu%s, "
""UINT64F" p, "UINT64F" b, "UINT64F" e, "UINT64F" last_packet, %.9f delay_min, %.9f delay_avg, %.9f delay_max\n", ""UINT64F" p, "UINT64F" b, "UINT64F" e, "UINT64F" last_packet, %.9f delay_min, %.9f delay_avg, %.9f delay_max\n",
md->index, md->index,
local_addr, (unsigned int) (ps->sfd ? ps->sfd->fd.localport : 0), local_addr, (unsigned int) (ps->sfd ? ps->sfd->fd.localport : 0),
@ -342,7 +299,7 @@ static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m
(double) ps->stats.delay_max / 1000000); (double) ps->stats.delay_max / 1000000);
} }
#else #else
printlen = snprintf(replybuffer,(outbufend-replybuffer), "------ Media #%u, %15s:%-5u <> %15s:%-5u%s, " streambuf_printf(replybuffer, "------ Media #%u, %15s:%-5u <> %15s:%-5u%s, "
""UINT64F" p, "UINT64F" b, "UINT64F" e, "UINT64F" last_packet\n", ""UINT64F" p, "UINT64F" b, "UINT64F" e, "UINT64F" last_packet\n",
md->index, md->index,
local_addr, (unsigned int) (ps->selected_sfd ? ps->selected_sfd->socket.local.port : 0), local_addr, (unsigned int) (ps->selected_sfd ? ps->selected_sfd->socket.local.port : 0),
@ -353,19 +310,16 @@ static void cli_incoming_list_callid(char* buffer, int len, struct callmaster* m
atomic64_get(&ps->stats.errors), atomic64_get(&ps->stats.errors),
atomic64_get(&ps->last_packet)); atomic64_get(&ps->last_packet));
#endif #endif
ADJUSTLEN(printlen,outbufend,replybuffer);
} }
} }
} }
printlen = snprintf(replybuffer,(outbufend-replybuffer), "\n"); streambuf_printf(replybuffer, "\n");
ADJUSTLEN(printlen,outbufend,replybuffer);
rwlock_unlock_w(&c->master_lock); // because of call_get(..) rwlock_unlock_w(&c->master_lock); // because of call_get(..)
obj_put(c); obj_put(c);
} }
static void cli_incoming_list_sessions(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { static void cli_incoming_list_sessions(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) {
int printlen=0;
GHashTableIter iter; GHashTableIter iter;
gpointer key, value; gpointer key, value;
str *ptrkey; str *ptrkey;
@ -377,8 +331,7 @@ static void cli_incoming_list_sessions(char* buffer, int len, struct callmaster*
static const char* LIST_FOREIGN = "foreign"; static const char* LIST_FOREIGN = "foreign";
if (len<=1) { if (len<=1) {
printlen = snprintf(replybuffer, outbufend-replybuffer, "%s\n", "More parameters required."); streambuf_printf(replybuffer, "%s\n", "More parameters required.");
ADJUSTLEN(printlen,outbufend,replybuffer);
return; return;
} }
++buffer; --len; // one space ++buffer; --len; // one space
@ -386,8 +339,7 @@ static void cli_incoming_list_sessions(char* buffer, int len, struct callmaster*
rwlock_lock_r(&m->hashlock); rwlock_lock_r(&m->hashlock);
if (g_hash_table_size(m->callhash)==0) { if (g_hash_table_size(m->callhash)==0) {
printlen = snprintf(replybuffer, outbufend-replybuffer, "No sessions on this media relay.\n"); streambuf_printf(replybuffer, "No sessions on this media relay.\n");
ADJUSTLEN(printlen,outbufend,replybuffer);
rwlock_unlock_r(&m->hashlock); rwlock_unlock_r(&m->hashlock);
return; return;
} }
@ -418,8 +370,7 @@ static void cli_incoming_list_sessions(char* buffer, int len, struct callmaster*
break; break;
} }
printlen = snprintf(replybuffer, outbufend-replybuffer, "callid: %60s | deletionmark:%4s | created:%12i | proxy:%s | redis_keyspace:%i | foreign:%s\n", ptrkey->s, call->ml_deleted?"yes":"no", (int)call->created.tv_sec, call->created_from, call->redis_hosted_db, IS_FOREIGN_CALL(call)?"yes":"no"); streambuf_printf(replybuffer, "callid: %60s | deletionmark:%4s | created:%12i | proxy:%s | redis_keyspace:%i | foreign:%s\n", ptrkey->s, call->ml_deleted?"yes":"no", (int)call->created.tv_sec, call->created_from, call->redis_hosted_db, IS_FOREIGN_CALL(call)?"yes":"no");
ADJUSTLEN(printlen,outbufend,replybuffer);
} }
rwlock_unlock_r(&m->hashlock); rwlock_unlock_r(&m->hashlock);
@ -427,24 +378,21 @@ static void cli_incoming_list_sessions(char* buffer, int len, struct callmaster*
; ;
} else if (len>=strlen(LIST_OWN) && strncmp(buffer,LIST_OWN,strlen(LIST_OWN)) == 0) { } else if (len>=strlen(LIST_OWN) && strncmp(buffer,LIST_OWN,strlen(LIST_OWN)) == 0) {
if (!found_own) { if (!found_own) {
printlen = snprintf(replybuffer, outbufend-replybuffer, "No own sessions on this media relay.\n"); streambuf_printf(replybuffer, "No own sessions on this media relay.\n");
ADJUSTLEN(printlen,outbufend,replybuffer);
} }
} else if (len>=strlen(LIST_FOREIGN) && strncmp(buffer,LIST_FOREIGN,strlen(LIST_FOREIGN)) == 0) { } else if (len>=strlen(LIST_FOREIGN) && strncmp(buffer,LIST_FOREIGN,strlen(LIST_FOREIGN)) == 0) {
if (!found_foreign) { if (!found_foreign) {
printlen = snprintf(replybuffer, outbufend-replybuffer, "No foreign sessions on this media relay.\n"); streambuf_printf(replybuffer, "No foreign sessions on this media relay.\n");
ADJUSTLEN(printlen,outbufend,replybuffer);
} }
} else { } else {
// list session for callid // list session for callid
cli_incoming_list_callid(buffer, len, m, replybuffer, outbufend); cli_incoming_list_callid(buffer, len, m, replybuffer);
} }
return; return;
} }
static void cli_incoming_set_maxopenfiles(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { static void cli_incoming_set_maxopenfiles(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) {
int printlen = 0;
unsigned long open_files_num; unsigned long open_files_num;
str open_files; str open_files;
pid_t pid; pid_t pid;
@ -454,8 +402,7 @@ static void cli_incoming_set_maxopenfiles(char* buffer, int len, struct callmast
unsigned long min_open_files_num = (1 << 16); unsigned long min_open_files_num = (1 << 16);
if (len <= 1) { if (len <= 1) {
printlen = snprintf(replybuffer,(outbufend-replybuffer), "%s\n", "More parameters required."); streambuf_printf(replybuffer, "%s\n", "More parameters required.");
ADJUSTLEN(printlen,outbufend,replybuffer);
return; return;
} }
@ -465,38 +412,31 @@ static void cli_incoming_set_maxopenfiles(char* buffer, int len, struct callmast
open_files_num = strtoul(open_files.s, &endptr, 10); open_files_num = strtoul(open_files.s, &endptr, 10);
if ((errno == ERANGE && (open_files_num == ULONG_MAX)) || (errno != 0 && open_files_num == 0)) { if ((errno == ERANGE && (open_files_num == ULONG_MAX)) || (errno != 0 && open_files_num == 0)) {
printlen = snprintf (replybuffer,(outbufend-replybuffer), "Fail setting open_files to %.*s; errno=%d\n", open_files.len, open_files.s, errno); streambuf_printf(replybuffer, "Fail setting open_files to %.*s; errno=%d\n", open_files.len, open_files.s, errno);
ADJUSTLEN(printlen,outbufend,replybuffer);
return; return;
} else if (endptr == open_files.s) { } else if (endptr == open_files.s) {
printlen = snprintf (replybuffer,(outbufend-replybuffer), "Fail setting open_files to %.*s; no digists found\n", open_files.len, open_files.s); streambuf_printf(replybuffer, "Fail setting open_files to %.*s; no digists found\n", open_files.len, open_files.s);
ADJUSTLEN(printlen,outbufend,replybuffer);
return; return;
} else if (open_files_num < min_open_files_num) { } else if (open_files_num < min_open_files_num) {
printlen = snprintf (replybuffer,(outbufend-replybuffer), "Fail setting open_files to %lu; can't set it under %lu\n", open_files_num, min_open_files_num); streambuf_printf(replybuffer, "Fail setting open_files to %lu; can't set it under %lu\n", open_files_num, min_open_files_num);
ADJUSTLEN(printlen,outbufend,replybuffer);
return; return;
} else if (rlim(RLIMIT_NOFILE, open_files_num) == -1){ } else if (rlim(RLIMIT_NOFILE, open_files_num) == -1){
printlen = snprintf (replybuffer,(outbufend-replybuffer), "Fail setting open_files to %lu; errno = %d\n", open_files_num, errno); streambuf_printf(replybuffer, "Fail setting open_files to %lu; errno = %d\n", open_files_num, errno);
ADJUSTLEN(printlen,outbufend,replybuffer);
return; return;
} else { } else {
pid = getpid(); pid = getpid();
printlen = snprintf (replybuffer,(outbufend-replybuffer), "Success setting open_files to %lu; cat /proc/%u/limits\n", open_files_num, pid); streambuf_printf(replybuffer, "Success setting open_files to %lu; cat /proc/%u/limits\n", open_files_num, pid);
ADJUSTLEN(printlen,outbufend,replybuffer);
} }
} }
static void cli_incoming_set_maxsessions(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { static void cli_incoming_set_maxsessions(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) {
int printlen = 0;
long maxsessions_num; long maxsessions_num;
int disabled = -1; int disabled = -1;
str maxsessions; str maxsessions;
char *endptr; char *endptr;
if (len <= 1) { if (len <= 1) {
printlen = snprintf(replybuffer,(outbufend-replybuffer), "%s\n", "More parameters required."); streambuf_printf(replybuffer, "%s\n", "More parameters required.");
ADJUSTLEN(printlen,outbufend,replybuffer);
return; return;
} }
@ -506,42 +446,35 @@ static void cli_incoming_set_maxsessions(char* buffer, int len, struct callmaste
maxsessions_num = strtol(maxsessions.s, &endptr, 10); maxsessions_num = strtol(maxsessions.s, &endptr, 10);
if ((errno == ERANGE && (maxsessions_num == LONG_MAX || maxsessions_num == LONG_MIN)) || (errno != 0 && maxsessions_num == 0)) { if ((errno == ERANGE && (maxsessions_num == LONG_MAX || maxsessions_num == LONG_MIN)) || (errno != 0 && maxsessions_num == 0)) {
printlen = snprintf (replybuffer,(outbufend-replybuffer), "Fail setting maxsessions to %.*s; errno=%d\n", maxsessions.len, maxsessions.s, errno); streambuf_printf(replybuffer, "Fail setting maxsessions to %.*s; errno=%d\n", maxsessions.len, maxsessions.s, errno);
ADJUSTLEN(printlen,outbufend,replybuffer);
return; return;
} else if (endptr == maxsessions.s) { } else if (endptr == maxsessions.s) {
printlen = snprintf (replybuffer,(outbufend-replybuffer), "Fail setting maxsessions to %.*s; no digists found\n", maxsessions.len, maxsessions.s); streambuf_printf(replybuffer, "Fail setting maxsessions to %.*s; no digists found\n", maxsessions.len, maxsessions.s);
ADJUSTLEN(printlen,outbufend,replybuffer);
return; return;
} else if (maxsessions_num < disabled) { } else if (maxsessions_num < disabled) {
printlen = snprintf (replybuffer,(outbufend-replybuffer), "Fail setting maxsessions to %ld; either positive or -1 values allowed\n", maxsessions_num); streambuf_printf(replybuffer, "Fail setting maxsessions to %ld; either positive or -1 values allowed\n", maxsessions_num);
ADJUSTLEN(printlen,outbufend,replybuffer);
} else if (maxsessions_num == disabled) { } else if (maxsessions_num == disabled) {
rwlock_lock_w(&m->conf.config_lock); rwlock_lock_w(&m->conf.config_lock);
m->conf.max_sessions = maxsessions_num; m->conf.max_sessions = maxsessions_num;
rwlock_unlock_w(&m->conf.config_lock); rwlock_unlock_w(&m->conf.config_lock);
printlen = snprintf (replybuffer,(outbufend-replybuffer), "Success setting maxsessions to %ld; disable feature\n", maxsessions_num); streambuf_printf(replybuffer, "Success setting maxsessions to %ld; disable feature\n", maxsessions_num);
ADJUSTLEN(printlen,outbufend,replybuffer);
} else { } else {
rwlock_lock_w(&m->conf.config_lock); rwlock_lock_w(&m->conf.config_lock);
m->conf.max_sessions = maxsessions_num; m->conf.max_sessions = maxsessions_num;
rwlock_unlock_w(&m->conf.config_lock); rwlock_unlock_w(&m->conf.config_lock);
printlen = snprintf (replybuffer,(outbufend-replybuffer), "Success setting maxsessions to %ld\n", maxsessions_num); streambuf_printf(replybuffer, "Success setting maxsessions to %ld\n", maxsessions_num);
ADJUSTLEN(printlen,outbufend,replybuffer);
} }
return; return;
} }
static void cli_incoming_set_timeout(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend, unsigned int *conf_timeout) { static void cli_incoming_set_timeout(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer, unsigned int *conf_timeout) {
int printlen = 0;
unsigned long timeout_num; unsigned long timeout_num;
str timeout; str timeout;
char *endptr; char *endptr;
if (len <= 1) { if (len <= 1) {
printlen = snprintf(replybuffer,(outbufend-replybuffer), "%s\n", "More parameters required."); streambuf_printf(replybuffer, "%s\n", "More parameters required.");
ADJUSTLEN(printlen,outbufend,replybuffer);
return; return;
} }
@ -551,26 +484,21 @@ static void cli_incoming_set_timeout(char* buffer, int len, struct callmaster* m
timeout_num = strtoul(timeout.s, &endptr, 10); timeout_num = strtoul(timeout.s, &endptr, 10);
if ((errno == ERANGE && (timeout_num == ULONG_MAX)) || (errno != 0 && timeout_num == 0)) { if ((errno == ERANGE && (timeout_num == ULONG_MAX)) || (errno != 0 && timeout_num == 0)) {
printlen = snprintf (replybuffer,(outbufend-replybuffer), "Fail setting timeout to %.*s; errno=%d\n", timeout.len, timeout.s, errno); streambuf_printf(replybuffer, "Fail setting timeout to %.*s; errno=%d\n", timeout.len, timeout.s, errno);
ADJUSTLEN(printlen,outbufend,replybuffer);
return; return;
} else if (endptr == timeout.s) { } else if (endptr == timeout.s) {
printlen = snprintf (replybuffer,(outbufend-replybuffer), "Fail setting timeout to %.*s; no digists found\n", timeout.len, timeout.s); streambuf_printf(replybuffer, "Fail setting timeout to %.*s; no digists found\n", timeout.len, timeout.s);
ADJUSTLEN(printlen,outbufend,replybuffer);
return; return;
} else { } else {
/* don't lock anything while writing the value - only this command modifies its value */ /* don't lock anything while writing the value - only this command modifies its value */
rwlock_lock_w(&m->conf.config_lock); rwlock_lock_w(&m->conf.config_lock);
*conf_timeout = timeout_num; *conf_timeout = timeout_num;
rwlock_unlock_w(&m->conf.config_lock); rwlock_unlock_w(&m->conf.config_lock);
printlen = snprintf (replybuffer,(outbufend-replybuffer), "Success setting timeout to %lu\n", timeout_num); streambuf_printf(replybuffer, "Success setting timeout to %lu\n", timeout_num);
ADJUSTLEN(printlen,outbufend,replybuffer);
} }
} }
static void cli_incoming_list(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { static void cli_incoming_list(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) {
int printlen=0;
static const char* LIST_NUMSESSIONS = "numsessions"; static const char* LIST_NUMSESSIONS = "numsessions";
static const char* LIST_SESSIONS = "sessions"; static const char* LIST_SESSIONS = "sessions";
static const char* LIST_TOTALS = "totals"; static const char* LIST_TOTALS = "totals";
@ -579,40 +507,33 @@ static void cli_incoming_list(char* buffer, int len, struct callmaster* m, char*
static const char* LIST_TIMEOUT = "timeout"; static const char* LIST_TIMEOUT = "timeout";
if (len<=1) { if (len<=1) {
printlen = snprintf(replybuffer, outbufend-replybuffer, "%s\n", "More parameters required."); streambuf_printf(replybuffer, "%s\n", "More parameters required.");
ADJUSTLEN(printlen,outbufend,replybuffer);
return; return;
} }
++buffer; --len; // one space ++buffer; --len; // one space
if (len>=strlen(LIST_NUMSESSIONS) && strncmp(buffer,LIST_NUMSESSIONS,strlen(LIST_NUMSESSIONS)) == 0) { if (len>=strlen(LIST_NUMSESSIONS) && strncmp(buffer,LIST_NUMSESSIONS,strlen(LIST_NUMSESSIONS)) == 0) {
rwlock_lock_r(&m->hashlock); rwlock_lock_r(&m->hashlock);
printlen = snprintf(replybuffer, outbufend-replybuffer, "Current sessions own: "UINT64F"\n", g_hash_table_size(m->callhash) - atomic64_get(&m->stats.foreign_sessions)); streambuf_printf(replybuffer, "Current sessions own: "UINT64F"\n", g_hash_table_size(m->callhash) - atomic64_get(&m->stats.foreign_sessions));
ADJUSTLEN(printlen,outbufend,replybuffer); streambuf_printf(replybuffer, "Current sessions foreign: "UINT64F"\n", atomic64_get(&m->stats.foreign_sessions));
printlen = snprintf(replybuffer, outbufend-replybuffer, "Current sessions foreign: "UINT64F"\n", atomic64_get(&m->stats.foreign_sessions)); streambuf_printf(replybuffer, "Current sessions total: %i\n", g_hash_table_size(m->callhash));
ADJUSTLEN(printlen,outbufend,replybuffer);
printlen = snprintf(replybuffer, outbufend-replybuffer, "Current sessions total: %i\n", g_hash_table_size(m->callhash));
ADJUSTLEN(printlen,outbufend,replybuffer);
rwlock_unlock_r(&m->hashlock); rwlock_unlock_r(&m->hashlock);
} else if (len>=strlen(LIST_SESSIONS) && strncmp(buffer,LIST_SESSIONS,strlen(LIST_SESSIONS)) == 0) { } else if (len>=strlen(LIST_SESSIONS) && strncmp(buffer,LIST_SESSIONS,strlen(LIST_SESSIONS)) == 0) {
cli_incoming_list_sessions(buffer+strlen(LIST_SESSIONS), len-strlen(LIST_SESSIONS), m, replybuffer, outbufend); cli_incoming_list_sessions(buffer+strlen(LIST_SESSIONS), len-strlen(LIST_SESSIONS), m, replybuffer);
} else if (len>=strlen(LIST_TOTALS) && strncmp(buffer,LIST_TOTALS,strlen(LIST_TOTALS)) == 0) { } else if (len>=strlen(LIST_TOTALS) && strncmp(buffer,LIST_TOTALS,strlen(LIST_TOTALS)) == 0) {
cli_incoming_list_totals(buffer+strlen(LIST_TOTALS), len-strlen(LIST_TOTALS), m, replybuffer, outbufend); cli_incoming_list_totals(buffer+strlen(LIST_TOTALS), len-strlen(LIST_TOTALS), m, replybuffer);
} else if (len>=strlen(LIST_MAX_SESSIONS) && strncmp(buffer,LIST_MAX_SESSIONS,strlen(LIST_MAX_SESSIONS)) == 0) { } else if (len>=strlen(LIST_MAX_SESSIONS) && strncmp(buffer,LIST_MAX_SESSIONS,strlen(LIST_MAX_SESSIONS)) == 0) {
cli_incoming_list_maxsessions(buffer+strlen(LIST_MAX_SESSIONS), len-strlen(LIST_MAX_SESSIONS), m, replybuffer, outbufend); cli_incoming_list_maxsessions(buffer+strlen(LIST_MAX_SESSIONS), len-strlen(LIST_MAX_SESSIONS), m, replybuffer);
} else if (len>=strlen(LIST_MAX_OPEN_FILES) && strncmp(buffer,LIST_MAX_OPEN_FILES,strlen(LIST_MAX_OPEN_FILES)) == 0) { } else if (len>=strlen(LIST_MAX_OPEN_FILES) && strncmp(buffer,LIST_MAX_OPEN_FILES,strlen(LIST_MAX_OPEN_FILES)) == 0) {
cli_incoming_list_maxopenfiles(buffer+strlen(LIST_MAX_OPEN_FILES), len-strlen(LIST_MAX_OPEN_FILES), m, replybuffer, outbufend); cli_incoming_list_maxopenfiles(buffer+strlen(LIST_MAX_OPEN_FILES), len-strlen(LIST_MAX_OPEN_FILES), m, replybuffer);
} else if (len>=strlen(LIST_TIMEOUT) && strncmp(buffer,LIST_TIMEOUT,strlen(LIST_TIMEOUT)) == 0) { } else if (len>=strlen(LIST_TIMEOUT) && strncmp(buffer,LIST_TIMEOUT,strlen(LIST_TIMEOUT)) == 0) {
cli_incoming_list_timeout(buffer+strlen(LIST_TIMEOUT), len-strlen(LIST_TIMEOUT), m, replybuffer, outbufend); cli_incoming_list_timeout(buffer+strlen(LIST_TIMEOUT), len-strlen(LIST_TIMEOUT), m, replybuffer);
} else { } else {
printlen = snprintf(replybuffer, outbufend-replybuffer, "%s:%s\n", "Unknown 'list' command", buffer); streambuf_printf(replybuffer, "%s:%s\n", "Unknown 'list' command", buffer);
ADJUSTLEN(printlen,outbufend,replybuffer);
} }
} }
static void cli_incoming_set(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { static void cli_incoming_set(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) {
int printlen=0;
static const char* SET_MAX_OPEN_FILES = "maxopenfiles"; static const char* SET_MAX_OPEN_FILES = "maxopenfiles";
static const char* SET_MAX_SESSIONS = "maxsessions"; static const char* SET_MAX_SESSIONS = "maxsessions";
static const char* SET_TIMEOUT = "timeout"; static const char* SET_TIMEOUT = "timeout";
@ -620,38 +541,34 @@ static void cli_incoming_set(char* buffer, int len, struct callmaster* m, char*
static const char* SET_FINAL_TIMEOUT = "finaltimeout"; static const char* SET_FINAL_TIMEOUT = "finaltimeout";
if (len<=1) { if (len<=1) {
printlen = snprintf(replybuffer, outbufend-replybuffer, "%s\n", "More parameters required."); streambuf_printf(replybuffer, "%s\n", "More parameters required.");
ADJUSTLEN(printlen,outbufend,replybuffer);
return; return;
} }
++buffer; --len; // one space ++buffer; --len; // one space
if (len>=strlen(SET_MAX_OPEN_FILES) && strncmp(buffer,SET_MAX_OPEN_FILES,strlen(SET_MAX_OPEN_FILES)) == 0) { if (len>=strlen(SET_MAX_OPEN_FILES) && strncmp(buffer,SET_MAX_OPEN_FILES,strlen(SET_MAX_OPEN_FILES)) == 0) {
cli_incoming_set_maxopenfiles(buffer+strlen(SET_MAX_OPEN_FILES), len-strlen(SET_MAX_OPEN_FILES), m, replybuffer, outbufend); cli_incoming_set_maxopenfiles(buffer+strlen(SET_MAX_OPEN_FILES), len-strlen(SET_MAX_OPEN_FILES), m, replybuffer);
} else if (len>=strlen(SET_MAX_SESSIONS) && strncmp(buffer,SET_MAX_SESSIONS,strlen(SET_MAX_SESSIONS)) == 0) { } else if (len>=strlen(SET_MAX_SESSIONS) && strncmp(buffer,SET_MAX_SESSIONS,strlen(SET_MAX_SESSIONS)) == 0) {
cli_incoming_set_maxsessions(buffer+strlen(SET_MAX_SESSIONS), len-strlen(SET_MAX_SESSIONS), m, replybuffer, outbufend); cli_incoming_set_maxsessions(buffer+strlen(SET_MAX_SESSIONS), len-strlen(SET_MAX_SESSIONS), m, replybuffer);
} else if (len>=strlen(SET_TIMEOUT) && strncmp(buffer,SET_TIMEOUT,strlen(SET_TIMEOUT)) == 0) { } else if (len>=strlen(SET_TIMEOUT) && strncmp(buffer,SET_TIMEOUT,strlen(SET_TIMEOUT)) == 0) {
cli_incoming_set_timeout(buffer+strlen(SET_TIMEOUT), len-strlen(SET_TIMEOUT), m, replybuffer, outbufend, &m->conf.timeout); cli_incoming_set_timeout(buffer+strlen(SET_TIMEOUT), len-strlen(SET_TIMEOUT), m, replybuffer, &m->conf.timeout);
} else if (len>=strlen(SET_SILENT_TIMEOUT) && strncmp(buffer,SET_SILENT_TIMEOUT,strlen(SET_SILENT_TIMEOUT)) == 0) { } else if (len>=strlen(SET_SILENT_TIMEOUT) && strncmp(buffer,SET_SILENT_TIMEOUT,strlen(SET_SILENT_TIMEOUT)) == 0) {
cli_incoming_set_timeout(buffer+strlen(SET_SILENT_TIMEOUT), len-strlen(SET_SILENT_TIMEOUT), m, replybuffer, outbufend, &m->conf.silent_timeout); cli_incoming_set_timeout(buffer+strlen(SET_SILENT_TIMEOUT), len-strlen(SET_SILENT_TIMEOUT), m, replybuffer, &m->conf.silent_timeout);
} else if (len>=strlen(SET_FINAL_TIMEOUT) && strncmp(buffer,SET_FINAL_TIMEOUT,strlen(SET_FINAL_TIMEOUT)) == 0) { } else if (len>=strlen(SET_FINAL_TIMEOUT) && strncmp(buffer,SET_FINAL_TIMEOUT,strlen(SET_FINAL_TIMEOUT)) == 0) {
cli_incoming_set_timeout(buffer+strlen(SET_FINAL_TIMEOUT), len-strlen(SET_FINAL_TIMEOUT), m, replybuffer, outbufend, &m->conf.final_timeout); cli_incoming_set_timeout(buffer+strlen(SET_FINAL_TIMEOUT), len-strlen(SET_FINAL_TIMEOUT), m, replybuffer, &m->conf.final_timeout);
} else { } else {
printlen = snprintf(replybuffer, outbufend-replybuffer, "%s:%s\n", "Unknown 'set' command", buffer); streambuf_printf(replybuffer, "%s:%s\n", "Unknown 'set' command", buffer);
ADJUSTLEN(printlen,outbufend,replybuffer);
} }
} }
static void cli_incoming_terminate(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { static void cli_incoming_terminate(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) {
str termparam; str termparam;
struct call* c=0; struct call* c=0;
int printlen=0;
struct call_monologue *ml; struct call_monologue *ml;
GList *i; GList *i;
if (len<=1) { if (len<=1) {
printlen = snprintf(replybuffer, outbufend-replybuffer, "%s\n", "More parameters required."); streambuf_printf(replybuffer, "%s\n", "More parameters required.");
ADJUSTLEN(printlen,outbufend,replybuffer);
return; return;
} }
++buffer; --len; // one space ++buffer; --len; // one space
@ -667,8 +584,7 @@ static void cli_incoming_terminate(char* buffer, int len, struct callmaster* m,
// update cli // update cli
ilog(LOG_INFO,"All calls terminated by operator."); ilog(LOG_INFO,"All calls terminated by operator.");
printlen = snprintf(replybuffer, outbufend-replybuffer, "%s\n", "All calls terminated by operator."); streambuf_printf(replybuffer, "%s\n", "All calls terminated by operator.");
ADJUSTLEN(printlen,outbufend,replybuffer);
return; return;
@ -679,8 +595,7 @@ static void cli_incoming_terminate(char* buffer, int len, struct callmaster* m,
// update cli // update cli
ilog(LOG_INFO,"All own calls terminated by operator."); ilog(LOG_INFO,"All own calls terminated by operator.");
printlen = snprintf(replybuffer, outbufend-replybuffer, "%s\n", "All own calls terminated by operator."); streambuf_printf(replybuffer, "%s\n", "All own calls terminated by operator.");
ADJUSTLEN(printlen,outbufend,replybuffer);
return; return;
@ -691,8 +606,7 @@ static void cli_incoming_terminate(char* buffer, int len, struct callmaster* m,
// update cli // update cli
ilog(LOG_INFO,"All foreign calls terminated by operator."); ilog(LOG_INFO,"All foreign calls terminated by operator.");
printlen = snprintf(replybuffer, outbufend-replybuffer, "%s\n", "All foreign calls terminated by operator."); streambuf_printf(replybuffer, "%s\n", "All foreign calls terminated by operator.");
ADJUSTLEN(printlen,outbufend,replybuffer);
return; return;
} }
@ -701,8 +615,7 @@ static void cli_incoming_terminate(char* buffer, int len, struct callmaster* m,
c = call_get(&termparam, m); c = call_get(&termparam, m);
if (!c) { if (!c) {
printlen = snprintf(replybuffer, outbufend-replybuffer, "\nCall Id not found (%s).\n\n",termparam.s); streambuf_printf(replybuffer, "\nCall Id not found (%s).\n\n",termparam.s);
ADJUSTLEN(printlen,outbufend,replybuffer);
return; return;
} }
@ -714,8 +627,7 @@ static void cli_incoming_terminate(char* buffer, int len, struct callmaster* m,
} }
} }
printlen = snprintf(replybuffer, outbufend-replybuffer, "\nCall Id (%s) successfully terminated by operator.\n\n",termparam.s); streambuf_printf(replybuffer, "\nCall Id (%s) successfully terminated by operator.\n\n",termparam.s);
ADJUSTLEN(printlen,outbufend,replybuffer);
ilog(LOG_WARN, "Call Id (%s) successfully terminated by operator.",termparam.s); ilog(LOG_WARN, "Call Id (%s) successfully terminated by operator.",termparam.s);
rwlock_unlock_w(&c->master_lock); rwlock_unlock_w(&c->master_lock);
@ -724,15 +636,13 @@ static void cli_incoming_terminate(char* buffer, int len, struct callmaster* m,
obj_put(c); obj_put(c);
} }
static void cli_incoming_ksadd(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { static void cli_incoming_ksadd(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) {
int printlen=0;
unsigned long uint_keyspace_db; unsigned long uint_keyspace_db;
str str_keyspace_db; str str_keyspace_db;
char *endptr; char *endptr;
if (len<=1) { if (len<=1) {
printlen = snprintf(replybuffer, outbufend-replybuffer, "%s\n", "More parameters required."); streambuf_printf(replybuffer, "%s\n", "More parameters required.");
ADJUSTLEN(printlen,outbufend,replybuffer);
return; return;
} }
++buffer; --len; // one space ++buffer; --len; // one space
@ -742,33 +652,30 @@ static void cli_incoming_ksadd(char* buffer, int len, struct callmaster* m, char
uint_keyspace_db = strtoul(str_keyspace_db.s, &endptr, 10); uint_keyspace_db = strtoul(str_keyspace_db.s, &endptr, 10);
if ((errno == ERANGE && (uint_keyspace_db == ULONG_MAX)) || (errno != 0 && uint_keyspace_db == 0)) { if ((errno == ERANGE && (uint_keyspace_db == ULONG_MAX)) || (errno != 0 && uint_keyspace_db == 0)) {
printlen = snprintf(replybuffer, outbufend-replybuffer, "Fail adding keyspace %.*s to redis notifications; errono=%d\n", str_keyspace_db.len, str_keyspace_db.s, errno); streambuf_printf(replybuffer, "Fail adding keyspace %.*s to redis notifications; errono=%d\n", str_keyspace_db.len, str_keyspace_db.s, errno);
} else if (endptr == str_keyspace_db.s) { } else if (endptr == str_keyspace_db.s) {
printlen = snprintf(replybuffer, outbufend-replybuffer, "Fail adding keyspace %.*s to redis notifications; no digists found\n", str_keyspace_db.len, str_keyspace_db.s); streambuf_printf(replybuffer, "Fail adding keyspace %.*s to redis notifications; no digists found\n", str_keyspace_db.len, str_keyspace_db.s);
} else { } else {
rwlock_lock_w(&m->conf.config_lock); rwlock_lock_w(&m->conf.config_lock);
if (!g_queue_find(m->conf.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db))) { if (!g_queue_find(m->conf.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db))) {
g_queue_push_tail(m->conf.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db)); g_queue_push_tail(m->conf.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db));
redis_notify_subscribe_action(m, SUBSCRIBE_KEYSPACE, uint_keyspace_db); redis_notify_subscribe_action(m, SUBSCRIBE_KEYSPACE, uint_keyspace_db);
printlen = snprintf(replybuffer, outbufend-replybuffer, "Success adding keyspace %lu to redis notifications.\n", uint_keyspace_db); streambuf_printf(replybuffer, "Success adding keyspace %lu to redis notifications.\n", uint_keyspace_db);
} else { } else {
printlen = snprintf(replybuffer, outbufend-replybuffer, "Keyspace %lu is already among redis notifications.\n", uint_keyspace_db); streambuf_printf(replybuffer, "Keyspace %lu is already among redis notifications.\n", uint_keyspace_db);
} }
rwlock_unlock_w(&m->conf.config_lock); rwlock_unlock_w(&m->conf.config_lock);
} }
ADJUSTLEN(printlen,outbufend,replybuffer);
} }
static void cli_incoming_ksrm(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { static void cli_incoming_ksrm(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) {
int printlen = 0;
GList *l; GList *l;
unsigned long uint_keyspace_db; unsigned long uint_keyspace_db;
str str_keyspace_db; str str_keyspace_db;
char *endptr; char *endptr;
if (len <= 1) { if (len <= 1) {
printlen = snprintf(replybuffer, outbufend-replybuffer, "%s\n", "More parameters required."); streambuf_printf(replybuffer, "%s\n", "More parameters required.");
ADJUSTLEN(printlen,outbufend,replybuffer);
return; return;
} }
++buffer; --len; // one space ++buffer; --len; // one space
@ -779,90 +686,62 @@ static void cli_incoming_ksrm(char* buffer, int len, struct callmaster* m, char*
rwlock_lock_w(&m->conf.config_lock); rwlock_lock_w(&m->conf.config_lock);
if ((errno == ERANGE && (uint_keyspace_db == ULONG_MAX)) || (errno != 0 && uint_keyspace_db == 0)) { if ((errno == ERANGE && (uint_keyspace_db == ULONG_MAX)) || (errno != 0 && uint_keyspace_db == 0)) {
printlen = snprintf(replybuffer, outbufend-replybuffer, "Fail removing keyspace %.*s to redis notifications; errono=%d\n", str_keyspace_db.len, str_keyspace_db.s, errno); streambuf_printf(replybuffer, "Fail removing keyspace %.*s to redis notifications; errono=%d\n", str_keyspace_db.len, str_keyspace_db.s, errno);
} else if (endptr == str_keyspace_db.s) { } else if (endptr == str_keyspace_db.s) {
printlen = snprintf(replybuffer, outbufend-replybuffer, "Fail removing keyspace %.*s to redis notifications; no digists found\n", str_keyspace_db.len, str_keyspace_db.s); streambuf_printf(replybuffer, "Fail removing keyspace %.*s to redis notifications; no digists found\n", str_keyspace_db.len, str_keyspace_db.s);
} else if ((l = g_queue_find(m->conf.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db)))) { } else if ((l = g_queue_find(m->conf.redis_subscribed_keyspaces, GUINT_TO_POINTER(uint_keyspace_db)))) {
// remove this keyspace // remove this keyspace
redis_notify_subscribe_action(m, UNSUBSCRIBE_KEYSPACE, uint_keyspace_db); redis_notify_subscribe_action(m, UNSUBSCRIBE_KEYSPACE, uint_keyspace_db);
g_queue_remove(m->conf.redis_subscribed_keyspaces, l->data); g_queue_remove(m->conf.redis_subscribed_keyspaces, l->data);
printlen = snprintf(replybuffer, outbufend-replybuffer, "Successfully unsubscribed from keyspace %lu.\n", uint_keyspace_db); streambuf_printf(replybuffer, "Successfully unsubscribed from keyspace %lu.\n", uint_keyspace_db);
// destroy foreign calls for this keyspace // destroy foreign calls for this keyspace
destroy_keyspace_foreign_calls(m, uint_keyspace_db); destroy_keyspace_foreign_calls(m, uint_keyspace_db);
// update cli // update cli
printlen = snprintf(replybuffer, outbufend-replybuffer, "Successfully removed all foreign calls for keyspace %lu.\n", uint_keyspace_db); streambuf_printf(replybuffer, "Successfully removed all foreign calls for keyspace %lu.\n", uint_keyspace_db);
} else { } else {
printlen = snprintf(replybuffer, outbufend-replybuffer, "Keyspace %lu is not among redis notifications.\n", uint_keyspace_db); streambuf_printf(replybuffer, "Keyspace %lu is not among redis notifications.\n", uint_keyspace_db);
} }
rwlock_unlock_w(&m->conf.config_lock); rwlock_unlock_w(&m->conf.config_lock);
ADJUSTLEN(printlen,outbufend,replybuffer);
} }
static void cli_incoming_kslist(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { static void cli_incoming_kslist(char* buffer, int len, struct callmaster* m, struct streambuf *replybuffer) {
int printlen=0;
GList *l; GList *l;
printlen = snprintf(replybuffer,(outbufend-replybuffer), "\nSubscribed-on keyspaces:\n"); streambuf_printf(replybuffer, "\nSubscribed-on keyspaces:\n");
ADJUSTLEN(printlen,outbufend,replybuffer);
rwlock_lock_r(&m->conf.config_lock); rwlock_lock_r(&m->conf.config_lock);
for (l = m->conf.redis_subscribed_keyspaces->head; l; l = l->next) { for (l = m->conf.redis_subscribed_keyspaces->head; l; l = l->next) {
printlen = snprintf(replybuffer,(outbufend-replybuffer), "%u ", GPOINTER_TO_UINT(l->data)); streambuf_printf(replybuffer, "%u ", GPOINTER_TO_UINT(l->data));
ADJUSTLEN(printlen,outbufend,replybuffer);
} }
rwlock_unlock_r(&m->conf.config_lock); rwlock_unlock_r(&m->conf.config_lock);
printlen = snprintf(replybuffer, outbufend-replybuffer, "\n"); streambuf_printf(replybuffer, "\n");
ADJUSTLEN(printlen,outbufend,replybuffer); }
static void cli_incoming(struct streambuf_stream *s) {
ilog(LOG_INFO, "New cli connection from %s", s->addr);
} }
static void cli_incoming(int fd, void *p, uintptr_t u) { static void cli_stream_readable(struct streambuf_stream *s) {
int nfd; struct cli *cli = (void *) s->parent;
struct sockaddr_in sin;
struct cli *cli = (void *) p;
socklen_t sinl;
static const int BUFLENGTH = 4096*1024;
char replybuffer[BUFLENGTH];
char* outbuf = replybuffer;
const char* outbufend = replybuffer+BUFLENGTH;
static const int MAXINPUT = 1024; static const int MAXINPUT = 1024;
char inbuf[MAXINPUT+1]; int inlen = 0;
int inlen = 0, readbytes = 0; char *inbuf;
int rc=0;
inbuf = streambuf_getline(s->inbuf);
memset(replybuffer, 0, BUFLENGTH); if (!inbuf) {
if (streambuf_bufsize(s->inbuf) > MAXINPUT) {
mutex_lock(&cli->lock); ilog(LOG_INFO, "Buffer length exceeded in CLI connection from %s", s->addr);
next: streambuf_stream_close(s);
sinl = sizeof(sin);
nfd = accept(fd, (struct sockaddr *) &sin, &sinl);
if (nfd == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
goto cleanup2;
} }
ilog(LOG_INFO, "Accept error:%s", strerror(errno)); return;
goto next;
} }
ilog(LOG_INFO, "New cli connection from " DF, DP(sin));
do {
readbytes = read(nfd, inbuf+inlen, MAXINPUT-inlen);
if (readbytes == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
ilog(LOG_INFO, "Could currently not read CLI commands. Reason:%s", strerror(errno));
goto cleanup;
}
ilog(LOG_INFO, "Could currently not read CLI commands. Reason:%s", strerror(errno));
}
inlen += readbytes;
} while (readbytes > 0 && inlen < sizeof(inbuf)-1);
inbuf[inlen] = 0;
ilog(LOG_INFO, "Got CLI command:%s",inbuf); ilog(LOG_INFO, "Got CLI command:%s",inbuf);
inlen = strlen(inbuf);
static const char* LIST = "list"; static const char* LIST = "list";
static const char* TERMINATE = "terminate"; static const char* TERMINATE = "terminate";
@ -872,72 +751,63 @@ next:
static const char* KSLIST = "kslist"; static const char* KSLIST = "kslist";
if (strncmp(inbuf,LIST,strlen(LIST)) == 0) { if (strncmp(inbuf,LIST,strlen(LIST)) == 0) {
cli_incoming_list(inbuf+strlen(LIST), inlen-strlen(LIST), cli->callmaster, outbuf, outbufend); cli_incoming_list(inbuf+strlen(LIST), inlen-strlen(LIST), cli->callmaster, s->outbuf);
} else if (strncmp(inbuf,TERMINATE,strlen(TERMINATE)) == 0) { } else if (strncmp(inbuf,TERMINATE,strlen(TERMINATE)) == 0) {
cli_incoming_terminate(inbuf+strlen(TERMINATE), inlen-strlen(TERMINATE), cli->callmaster, outbuf, outbufend); cli_incoming_terminate(inbuf+strlen(TERMINATE), inlen-strlen(TERMINATE), cli->callmaster, s->outbuf);
} else if (strncmp(inbuf,SET,strlen(SET)) == 0) { } else if (strncmp(inbuf,SET,strlen(SET)) == 0) {
cli_incoming_set(inbuf+strlen(SET), inlen-strlen(SET), cli->callmaster, outbuf, outbufend); cli_incoming_set(inbuf+strlen(SET), inlen-strlen(SET), cli->callmaster, s->outbuf);
} else if (strncmp(inbuf,KSADD,strlen(KSADD)) == 0) { } else if (strncmp(inbuf,KSADD,strlen(KSADD)) == 0) {
cli_incoming_ksadd(inbuf+strlen(KSADD), inlen-strlen(KSADD), cli->callmaster, outbuf, outbufend); cli_incoming_ksadd(inbuf+strlen(KSADD), inlen-strlen(KSADD), cli->callmaster, s->outbuf);
} else if (strncmp(inbuf,KSRM,strlen(KSRM)) == 0) { } else if (strncmp(inbuf,KSRM,strlen(KSRM)) == 0) {
cli_incoming_ksrm(inbuf+strlen(KSRM), inlen-strlen(KSRM), cli->callmaster, outbuf, outbufend); cli_incoming_ksrm(inbuf+strlen(KSRM), inlen-strlen(KSRM), cli->callmaster, s->outbuf);
} else if (strncmp(inbuf,KSLIST,strlen(KSLIST)) == 0) { } else if (strncmp(inbuf,KSLIST,strlen(KSLIST)) == 0) {
cli_incoming_kslist(inbuf+strlen(KSLIST), inlen-strlen(KSLIST), cli->callmaster, outbuf, outbufend); cli_incoming_kslist(inbuf+strlen(KSLIST), inlen-strlen(KSLIST), cli->callmaster, s->outbuf);
} else { } else {
sprintf(replybuffer, "%s:%s\n", "Unknown or incomplete command:", inbuf); streambuf_printf(s->outbuf, "%s:%s\n", "Unknown or incomplete command:", inbuf);
} }
do { free(inbuf);
rc += write( nfd, (char *)&replybuffer, strlen(replybuffer) ); streambuf_stream_shutdown(s);
} while (rc < strlen(replybuffer));
cleanup:
close(nfd);
/* in case multiple incoming connections exist, read all of them */
goto next;
cleanup2:
mutex_unlock(&cli->lock);
log_info_clear(); log_info_clear();
} }
static void control_closed(int fd, void *p, uintptr_t u) { struct cli *cli_new(struct poller *p, endpoint_t *ep, struct callmaster *m) {
abort();
}
struct cli *cli_new(struct poller *p, const endpoint_t *ep, struct callmaster *m) {
struct cli *c; struct cli *c;
socket_t sock;
struct poller_item i;
if (!p || !m) if (!p || !m)
return NULL; return NULL;
if (open_socket(&sock, SOCK_STREAM, ep->port, &ep->address)) c = obj_alloc0("cli", sizeof(*c), NULL);
return NULL;
if (listen(sock.fd, 5)) if (streambuf_listener_init(&c->listeners[0], p, ep,
goto fail; cli_incoming, cli_stream_readable,
NULL,
NULL,
&c->obj))
{
ilog(LOG_ERR, "Failed to open TCP control port: %s", strerror(errno));
goto fail;
}
if (ipv46_any_convert(ep)) {
if (streambuf_listener_init(&c->listeners[1], p, ep,
cli_incoming, cli_stream_readable,
NULL,
NULL,
&c->obj))
{
ilog(LOG_ERR, "Failed to open TCP control port: %s", strerror(errno));
goto fail;
}
}
c = obj_alloc0("cli_udp", sizeof(*c), NULL);
c->sock = sock;
c->poller = p; c->poller = p;
c->callmaster = m; c->callmaster = m;
mutex_init(&c->lock);
ZERO(i);
i.fd = sock.fd;
i.closed = control_closed;
i.readable = cli_incoming;
i.obj = &c->obj;
if (poller_add_item(p, &i))
goto fail2;
obj_put(c); obj_put(c);
return c; return c;
fail2:
obj_put(c);
fail: fail:
close_socket(&sock); // XXX streambuf_listener_close ...
obj_put(c);
return NULL; return NULL;
} }

@ -3,17 +3,17 @@
#include "socket.h" #include "socket.h"
#include "obj.h" #include "obj.h"
#include "tcp_listener.h"
struct cli { struct cli {
struct obj obj; struct obj obj;
struct callmaster *callmaster; struct callmaster *callmaster;
socket_t sock;
struct poller *poller; struct poller *poller;
mutex_t lock;
struct streambuf_listener listeners[2];
}; };
struct cli *cli_new(struct poller *p, const endpoint_t *, struct callmaster *m); struct cli *cli_new(struct poller *p, endpoint_t *, struct callmaster *m);
#endif /* CLI_UDP_H_ */ #endif /* CLI_UDP_H_ */

@ -104,7 +104,8 @@ static void streambuf_stream_closed(int fd, void *p, uintptr_t u) {
if (s->sock.fd == -1) if (s->sock.fd == -1)
return; return;
s->cb->closed_func(s); if (s->cb->closed_func)
s->cb->closed_func(s);
struct streambuf_listener *l = s->listener; struct streambuf_listener *l = s->listener;
mutex_lock(&l->lock); mutex_lock(&l->lock);
@ -117,7 +118,8 @@ static void streambuf_stream_closed(int fd, void *p, uintptr_t u) {
static void streambuf_stream_timer(int fd, void *p, uintptr_t u) { static void streambuf_stream_timer(int fd, void *p, uintptr_t u) {
struct streambuf_stream *s = p; struct streambuf_stream *s = p;
s->cb->timer_func(s); if (s->cb->timer_func)
s->cb->timer_func(s);
} }

Loading…
Cancel
Save