|
|
@ -33,34 +33,39 @@ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define die(x...) do { fprintf(stderr, x); exit(-1); } while(0) |
|
|
|
|
|
|
|
|
#define die(x...) do { \ |
|
|
|
|
|
fprintf(stderr, x); \ |
|
|
|
|
|
fprintf(stderr, "\n"); \ |
|
|
|
|
|
ilog(LOG_CRIT, x); \ |
|
|
|
|
|
exit(-1); \ |
|
|
|
|
|
} while(0) |
|
|
#define dlresolve(n) do { \ |
|
|
#define dlresolve(n) do { \ |
|
|
n ## _mod = dlsym(dlh, "mod_" #n); \ |
|
|
n ## _mod = dlsym(dlh, "mod_" #n); \ |
|
|
if (!n ## _mod) \ |
|
|
if (!n ## _mod) \ |
|
|
die("Failed to resolve symbol from plugin: %s\n", "mod_" #n); \ |
|
|
|
|
|
|
|
|
die("Failed to resolve symbol from plugin: %s", "mod_" #n); \ |
|
|
} while(0) |
|
|
} while(0) |
|
|
#define check_struct_size(x) do { \ |
|
|
#define check_struct_size(x) do { \ |
|
|
unsigned long *uip; \ |
|
|
unsigned long *uip; \ |
|
|
uip = dlsym(dlh, "__size_struct_" #x); \ |
|
|
uip = dlsym(dlh, "__size_struct_" #x); \ |
|
|
if (!uip) \ |
|
|
if (!uip) \ |
|
|
die("Failed to resolve symbol from plugin: %s\n", "__size_struct_" #x); \ |
|
|
|
|
|
|
|
|
die("Failed to resolve symbol from plugin: %s", "__size_struct_" #x); \ |
|
|
if (*uip != sizeof(struct x)) \ |
|
|
if (*uip != sizeof(struct x)) \ |
|
|
die("Struct size mismatch in plugin: %s\n", #x); \ |
|
|
|
|
|
|
|
|
die("Struct size mismatch in plugin: %s", #x); \ |
|
|
} while(0) |
|
|
} while(0) |
|
|
#define check_struct_offset(x,y) do { \ |
|
|
#define check_struct_offset(x,y) do { \ |
|
|
unsigned long *uip; \ |
|
|
unsigned long *uip; \ |
|
|
uip = dlsym(dlh, "__offset_struct_" #x "_" #y); \ |
|
|
uip = dlsym(dlh, "__offset_struct_" #x "_" #y); \ |
|
|
if (!uip) \ |
|
|
if (!uip) \ |
|
|
die("Failed to resolve symbol from plugin: %s\n", \ |
|
|
|
|
|
|
|
|
die("Failed to resolve symbol from plugin: %s", \ |
|
|
"__offset_struct_" #x "_" #y); \ |
|
|
"__offset_struct_" #x "_" #y); \ |
|
|
if (*uip != (unsigned long) &(((struct x *) 0)->y)) \ |
|
|
if (*uip != (unsigned long) &(((struct x *) 0)->y)) \ |
|
|
die("Struct offset mismatch in plugin: %s->%s\n", #x, #y); \ |
|
|
|
|
|
|
|
|
die("Struct offset mismatch in plugin: %s->%s", #x, #y); \ |
|
|
uip = dlsym(dlh, "__size_struct_" #x "_" #y); \ |
|
|
uip = dlsym(dlh, "__size_struct_" #x "_" #y); \ |
|
|
if (!uip) \ |
|
|
if (!uip) \ |
|
|
die("Failed to resolve symbol from plugin: %s\n", \ |
|
|
|
|
|
|
|
|
die("Failed to resolve symbol from plugin: %s", \ |
|
|
"__size_struct_" #x "_" #y); \ |
|
|
"__size_struct_" #x "_" #y); \ |
|
|
if (*uip != sizeof(((struct x *) 0)->y)) \ |
|
|
if (*uip != sizeof(((struct x *) 0)->y)) \ |
|
|
die("Struct member size mismatch in plugin: %s->%s\n", #x, #y); \ |
|
|
|
|
|
|
|
|
die("Struct member size mismatch in plugin: %s->%s", #x, #y); \ |
|
|
} while(0) |
|
|
} while(0) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -77,10 +82,7 @@ static int global_shutdown; |
|
|
|
|
|
|
|
|
static char *pidfile; |
|
|
static char *pidfile; |
|
|
static gboolean foreground; |
|
|
static gboolean foreground; |
|
|
static u_int32_t ipv4; |
|
|
|
|
|
static u_int32_t adv_ipv4; |
|
|
|
|
|
static struct in6_addr ipv6; |
|
|
|
|
|
static struct in6_addr adv_ipv6; |
|
|
|
|
|
|
|
|
static GQueue interfaces = G_QUEUE_INIT; |
|
|
static u_int32_t listenp; |
|
|
static u_int32_t listenp; |
|
|
static u_int16_t listenport; |
|
|
static u_int16_t listenport; |
|
|
static struct in6_addr udp_listenp; |
|
|
static struct in6_addr udp_listenp; |
|
|
@ -254,11 +256,51 @@ static void print_available_log_facilities () { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static struct interface_address *if_addr_parse(char *s) { |
|
|
|
|
|
str name; |
|
|
|
|
|
char *c; |
|
|
|
|
|
struct in6_addr addr, adv; |
|
|
|
|
|
struct interface_address *ifa; |
|
|
|
|
|
|
|
|
|
|
|
/* name */ |
|
|
|
|
|
c = strchr(s, '/'); |
|
|
|
|
|
if (c) { |
|
|
|
|
|
*c++ = 0; |
|
|
|
|
|
str_init(&name, s); |
|
|
|
|
|
s = c; |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
str_init(&name, "default"); |
|
|
|
|
|
|
|
|
|
|
|
/* advertised address */ |
|
|
|
|
|
c = strchr(s, '!'); |
|
|
|
|
|
if (c) |
|
|
|
|
|
*c++ = 0; |
|
|
|
|
|
|
|
|
|
|
|
/* address */ |
|
|
|
|
|
if (pton_46(&addr, s)) |
|
|
|
|
|
return NULL; |
|
|
|
|
|
|
|
|
|
|
|
adv = addr; |
|
|
|
|
|
if (c) { |
|
|
|
|
|
if (pton_46(&adv, c)) |
|
|
|
|
|
return NULL; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ifa = g_slice_alloc(sizeof(*ifa)); |
|
|
|
|
|
ifa->interface_name = name; |
|
|
|
|
|
ifa->addr = addr; |
|
|
|
|
|
ifa->advertised = adv; |
|
|
|
|
|
|
|
|
|
|
|
return ifa; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void options(int *argc, char ***argv) { |
|
|
static void options(int *argc, char ***argv) { |
|
|
char *ipv4s = NULL; |
|
|
|
|
|
char *adv_ipv4s = NULL; |
|
|
|
|
|
char *ipv6s = NULL; |
|
|
|
|
|
char *adv_ipv6s = NULL; |
|
|
|
|
|
|
|
|
char **if_a = NULL; |
|
|
|
|
|
char **iter; |
|
|
|
|
|
struct interface_address *ifa; |
|
|
char *listenps = NULL; |
|
|
char *listenps = NULL; |
|
|
char *listenudps = NULL; |
|
|
char *listenudps = NULL; |
|
|
char *listenngs = NULL; |
|
|
char *listenngs = NULL; |
|
|
@ -270,10 +312,7 @@ static void options(int *argc, char ***argv) { |
|
|
{ "version", 'v', 0, G_OPTION_ARG_NONE, &version, "Print build time and exit", NULL }, |
|
|
{ "version", 'v', 0, G_OPTION_ARG_NONE, &version, "Print build time and exit", NULL }, |
|
|
{ "table", 't', 0, G_OPTION_ARG_INT, &table, "Kernel table to use", "INT" }, |
|
|
{ "table", 't', 0, G_OPTION_ARG_INT, &table, "Kernel table to use", "INT" }, |
|
|
{ "no-fallback",'F', 0, G_OPTION_ARG_NONE, &no_fallback, "Only start when kernel module is available", NULL }, |
|
|
{ "no-fallback",'F', 0, G_OPTION_ARG_NONE, &no_fallback, "Only start when kernel module is available", NULL }, |
|
|
{ "ip", 'i', 0, G_OPTION_ARG_STRING, &ipv4s, "Local IPv4 address for RTP", "IP" }, |
|
|
|
|
|
{ "advertised-ip", 'a', 0, G_OPTION_ARG_STRING, &adv_ipv4s, "IPv4 address to advertise", "IP" }, |
|
|
|
|
|
{ "ip6", 'I', 0, G_OPTION_ARG_STRING, &ipv6s, "Local IPv6 address for RTP", "IP6" }, |
|
|
|
|
|
{ "advertised-ip6",'A',0,G_OPTION_ARG_STRING, &adv_ipv6s, "IPv6 address to advertise", "IP6" }, |
|
|
|
|
|
|
|
|
{ "interface", 'i', 0, G_OPTION_ARG_STRING_ARRAY,&if_a, "Local interface for RTP", "[NAME/]IP[!IP]"}, |
|
|
{ "listen-tcp", 'l', 0, G_OPTION_ARG_STRING, &listenps, "TCP port to listen on", "[IP:]PORT" }, |
|
|
{ "listen-tcp", 'l', 0, G_OPTION_ARG_STRING, &listenps, "TCP port to listen on", "[IP:]PORT" }, |
|
|
{ "listen-udp", 'u', 0, G_OPTION_ARG_STRING, &listenudps, "UDP port to listen on", "[IP46:]PORT" }, |
|
|
{ "listen-udp", 'u', 0, G_OPTION_ARG_STRING, &listenudps, "UDP port to listen on", "[IP46:]PORT" }, |
|
|
{ "listen-ng", 'n', 0, G_OPTION_ARG_STRING, &listenngs, "UDP port to listen on, NG protocol", "[IP46:]PORT" }, |
|
|
{ "listen-ng", 'n', 0, G_OPTION_ARG_STRING, &listenngs, "UDP port to listen on, NG protocol", "[IP46:]PORT" }, |
|
|
@ -287,10 +326,10 @@ static void options(int *argc, char ***argv) { |
|
|
{ "redis", 'r', 0, G_OPTION_ARG_STRING, &redisps, "Connect to Redis database", "IP:PORT" }, |
|
|
{ "redis", 'r', 0, G_OPTION_ARG_STRING, &redisps, "Connect to Redis database", "IP:PORT" }, |
|
|
{ "redis-db", 'R', 0, G_OPTION_ARG_INT, &redis_db, "Which Redis DB to use", "INT" }, |
|
|
{ "redis-db", 'R', 0, G_OPTION_ARG_INT, &redis_db, "Which Redis DB to use", "INT" }, |
|
|
{ "b2b-url", 'b', 0, G_OPTION_ARG_STRING, &b2b_url, "XMLRPC URL of B2B UA" , "STRING" }, |
|
|
{ "b2b-url", 'b', 0, G_OPTION_ARG_STRING, &b2b_url, "XMLRPC URL of B2B UA" , "STRING" }, |
|
|
{ "log-level", 'L', 0, G_OPTION_ARG_INT, (void *)&log_level, "Mask log priorities above this level", "INT" }, |
|
|
|
|
|
{ "log-facility", 0, 0, G_OPTION_ARG_STRING, &log_facility_s, "Syslog facility to use for logging", "daemon|local0|...|local7"}, |
|
|
|
|
|
|
|
|
{ "log-level", 'L', 0, G_OPTION_ARG_INT, (void *)&log_level,"Mask log priorities above this level","INT" }, |
|
|
|
|
|
{ "log-facility",0, 0, G_OPTION_ARG_STRING, &log_facility_s, "Syslog facility to use for logging", "daemon|local0|...|local7"}, |
|
|
{ "log-stderr", 'E', 0, G_OPTION_ARG_NONE, &_log_stderr, "Log on stderr instead of syslog", NULL }, |
|
|
{ "log-stderr", 'E', 0, G_OPTION_ARG_NONE, &_log_stderr, "Log on stderr instead of syslog", NULL }, |
|
|
{ "xmlrpc-format", 'x', 0, G_OPTION_ARG_INT, &xmlrpc_fmt, "XMLRPC timeout request format to use. 0: SEMS DI, 1: call-id only", "INT" }, |
|
|
|
|
|
|
|
|
{ "xmlrpc-format",'x', 0, G_OPTION_ARG_INT, &xmlrpc_fmt, "XMLRPC timeout request format to use. 0: SEMS DI, 1: call-id only", "INT" }, |
|
|
{ NULL, } |
|
|
{ NULL, } |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
@ -300,50 +339,38 @@ static void options(int *argc, char ***argv) { |
|
|
c = g_option_context_new(" - next-generation media proxy"); |
|
|
c = g_option_context_new(" - next-generation media proxy"); |
|
|
g_option_context_add_main_entries(c, e, NULL); |
|
|
g_option_context_add_main_entries(c, e, NULL); |
|
|
if (!g_option_context_parse(c, argc, argv, &er)) |
|
|
if (!g_option_context_parse(c, argc, argv, &er)) |
|
|
die("Bad command line: %s\n", er->message); |
|
|
|
|
|
|
|
|
die("Bad command line: %s", er->message); |
|
|
|
|
|
|
|
|
if (version) |
|
|
if (version) |
|
|
die("%s\n", RTPENGINE_VERSION); |
|
|
|
|
|
|
|
|
die("%s", RTPENGINE_VERSION); |
|
|
|
|
|
|
|
|
if (!ipv4s) |
|
|
|
|
|
die("Missing option --ip\n"); |
|
|
|
|
|
|
|
|
if (!if_a) |
|
|
|
|
|
die("Missing option --interface"); |
|
|
if (!listenps && !listenudps && !listenngs) |
|
|
if (!listenps && !listenudps && !listenngs) |
|
|
die("Missing option --listen-tcp, --listen-udp or --listen-ng\n"); |
|
|
|
|
|
|
|
|
die("Missing option --listen-tcp, --listen-udp or --listen-ng"); |
|
|
|
|
|
|
|
|
ipv4 = inet_addr(ipv4s); |
|
|
|
|
|
if (ipv4 == -1) |
|
|
|
|
|
die("Invalid IPv4 address (--ip)\n"); |
|
|
|
|
|
|
|
|
|
|
|
if (adv_ipv4s) { |
|
|
|
|
|
adv_ipv4 = inet_addr(adv_ipv4s); |
|
|
|
|
|
if (adv_ipv4 == -1) |
|
|
|
|
|
die("Invalid IPv4 address (--advertised-ip)\n"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (ipv6s) { |
|
|
|
|
|
if (smart_pton(AF_INET6, ipv6s, &ipv6) != 1) |
|
|
|
|
|
die("Invalid IPv6 address (--ip6)\n"); |
|
|
|
|
|
} |
|
|
|
|
|
if (adv_ipv6s) { |
|
|
|
|
|
if (smart_pton(AF_INET6, adv_ipv6s, &adv_ipv6) != 1) |
|
|
|
|
|
die("Invalid IPv6 address (--advertised-ip6)\n"); |
|
|
|
|
|
|
|
|
for (iter = if_a; *iter; iter++) { |
|
|
|
|
|
ifa = if_addr_parse(*iter); |
|
|
|
|
|
if (!ifa) |
|
|
|
|
|
die("Invalid interface specification: %s", *iter); |
|
|
|
|
|
g_queue_push_tail(&interfaces, ifa); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (listenps) { |
|
|
if (listenps) { |
|
|
if (parse_ip_port(&listenp, &listenport, listenps)) |
|
|
if (parse_ip_port(&listenp, &listenport, listenps)) |
|
|
die("Invalid IP or port (--listen-tcp)\n"); |
|
|
|
|
|
|
|
|
die("Invalid IP or port (--listen-tcp)"); |
|
|
} |
|
|
} |
|
|
if (listenudps) { |
|
|
if (listenudps) { |
|
|
if (parse_ip6_port(&udp_listenp, &udp_listenport, listenudps)) |
|
|
if (parse_ip6_port(&udp_listenp, &udp_listenport, listenudps)) |
|
|
die("Invalid IP or port (--listen-udp)\n"); |
|
|
|
|
|
|
|
|
die("Invalid IP or port (--listen-udp)"); |
|
|
} |
|
|
} |
|
|
if (listenngs) { |
|
|
if (listenngs) { |
|
|
if (parse_ip6_port(&ng_listenp, &ng_listenport, listenngs)) |
|
|
if (parse_ip6_port(&ng_listenp, &ng_listenport, listenngs)) |
|
|
die("Invalid IP or port (--listen-ng)\n"); |
|
|
|
|
|
|
|
|
die("Invalid IP or port (--listen-ng)"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (tos < 0 || tos > 255) |
|
|
if (tos < 0 || tos > 255) |
|
|
die("Invalid TOS value\n"); |
|
|
|
|
|
|
|
|
die("Invalid TOS value"); |
|
|
|
|
|
|
|
|
if (timeout <= 0) |
|
|
if (timeout <= 0) |
|
|
timeout = 60; |
|
|
timeout = 60; |
|
|
@ -352,17 +379,16 @@ static void options(int *argc, char ***argv) { |
|
|
|
|
|
|
|
|
if (redisps) { |
|
|
if (redisps) { |
|
|
if (parse_ip_port(&redis_ip, &redis_port, redisps) || !redis_ip) |
|
|
if (parse_ip_port(&redis_ip, &redis_port, redisps) || !redis_ip) |
|
|
die("Invalid IP or port (--redis)\n"); |
|
|
|
|
|
|
|
|
die("Invalid IP or port (--redis)"); |
|
|
if (redis_db < 0) |
|
|
if (redis_db < 0) |
|
|
die("Must specify Redis DB number (--redis-db) when using Redis\n"); |
|
|
|
|
|
|
|
|
die("Must specify Redis DB number (--redis-db) when using Redis"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (xmlrpc_fmt < 0 || xmlrpc_fmt > 1) { |
|
|
|
|
|
die("Invalid XMLRPC format\n"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (xmlrpc_fmt > 1) |
|
|
|
|
|
die("Invalid XMLRPC format"); |
|
|
|
|
|
|
|
|
if ((log_level < LOG_EMERG) || (log_level > LOG_DEBUG)) |
|
|
if ((log_level < LOG_EMERG) || (log_level > LOG_DEBUG)) |
|
|
die("Invalid log level (--log_level)\n"); |
|
|
|
|
|
|
|
|
die("Invalid log level (--log_level)"); |
|
|
setlogmask(LOG_UPTO(log_level)); |
|
|
setlogmask(LOG_UPTO(log_level)); |
|
|
|
|
|
|
|
|
if (log_facility_s) { |
|
|
if (log_facility_s) { |
|
|
@ -502,21 +528,18 @@ void create_everything(struct main_context *ctx) { |
|
|
no_kernel: |
|
|
no_kernel: |
|
|
ctx->p = poller_new(); |
|
|
ctx->p = poller_new(); |
|
|
if (!ctx->p) |
|
|
if (!ctx->p) |
|
|
die("poller creation failed\n"); |
|
|
|
|
|
|
|
|
die("poller creation failed"); |
|
|
|
|
|
|
|
|
ctx->m = callmaster_new(ctx->p); |
|
|
ctx->m = callmaster_new(ctx->p); |
|
|
if (!ctx->m) |
|
|
if (!ctx->m) |
|
|
die("callmaster creation failed\n"); |
|
|
|
|
|
|
|
|
die("callmaster creation failed"); |
|
|
|
|
|
|
|
|
dtls_timer(ctx->p); |
|
|
dtls_timer(ctx->p); |
|
|
|
|
|
|
|
|
ZERO(mc); |
|
|
ZERO(mc); |
|
|
mc.kernelfd = kfd; |
|
|
mc.kernelfd = kfd; |
|
|
mc.kernelid = table; |
|
|
mc.kernelid = table; |
|
|
mc.ipv4 = ipv4; |
|
|
|
|
|
mc.adv_ipv4 = adv_ipv4; |
|
|
|
|
|
mc.ipv6 = ipv6; |
|
|
|
|
|
mc.adv_ipv6 = adv_ipv6; |
|
|
|
|
|
|
|
|
mc.interfaces = &interfaces; |
|
|
mc.port_min = port_min; |
|
|
mc.port_min = port_min; |
|
|
mc.port_max = port_max; |
|
|
mc.port_max = port_max; |
|
|
mc.timeout = timeout; |
|
|
mc.timeout = timeout; |
|
|
@ -529,7 +552,7 @@ no_kernel: |
|
|
if (listenport) { |
|
|
if (listenport) { |
|
|
ct = control_tcp_new(ctx->p, listenp, listenport, ctx->m); |
|
|
ct = control_tcp_new(ctx->p, listenp, listenport, ctx->m); |
|
|
if (!ct) |
|
|
if (!ct) |
|
|
die("Failed to open TCP control connection port\n"); |
|
|
|
|
|
|
|
|
die("Failed to open TCP control connection port"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
cu = NULL; |
|
|
cu = NULL; |
|
|
@ -537,7 +560,7 @@ no_kernel: |
|
|
callmaster_exclude_port(ctx->m, udp_listenport); |
|
|
callmaster_exclude_port(ctx->m, udp_listenport); |
|
|
cu = control_udp_new(ctx->p, udp_listenp, udp_listenport, ctx->m); |
|
|
cu = control_udp_new(ctx->p, udp_listenp, udp_listenport, ctx->m); |
|
|
if (!cu) |
|
|
if (!cu) |
|
|
die("Failed to open UDP control connection port\n"); |
|
|
|
|
|
|
|
|
die("Failed to open UDP control connection port"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
cn = NULL; |
|
|
cn = NULL; |
|
|
@ -545,7 +568,7 @@ no_kernel: |
|
|
callmaster_exclude_port(ctx->m, ng_listenport); |
|
|
callmaster_exclude_port(ctx->m, ng_listenport); |
|
|
cn = control_ng_new(ctx->p, ng_listenp, ng_listenport, ctx->m); |
|
|
cn = control_ng_new(ctx->p, ng_listenp, ng_listenport, ctx->m); |
|
|
if (!cn) |
|
|
if (!cn) |
|
|
die("Failed to open UDP control connection port\n"); |
|
|
|
|
|
|
|
|
die("Failed to open UDP control connection port"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (redis_ip) { |
|
|
if (redis_ip) { |
|
|
@ -554,24 +577,25 @@ no_kernel: |
|
|
&& g_file_test("../../rtpengine-redis/redis.so", G_FILE_TEST_IS_REGULAR)) |
|
|
&& g_file_test("../../rtpengine-redis/redis.so", G_FILE_TEST_IS_REGULAR)) |
|
|
dlh = dlopen("../../rtpengine-redis/redis.so", RTLD_NOW | RTLD_GLOBAL); |
|
|
dlh = dlopen("../../rtpengine-redis/redis.so", RTLD_NOW | RTLD_GLOBAL); |
|
|
if (!dlh) |
|
|
if (!dlh) |
|
|
die("Failed to open redis plugin, aborting (%s)\n", dlerror()); |
|
|
|
|
|
|
|
|
die("Failed to open redis plugin, aborting (%s)", dlerror()); |
|
|
strp = dlsym(dlh, "__module_version"); |
|
|
strp = dlsym(dlh, "__module_version"); |
|
|
if (!strp || !*strp || strcmp(*strp, REDIS_MODULE_VERSION)) |
|
|
if (!strp || !*strp || strcmp(*strp, REDIS_MODULE_VERSION)) |
|
|
die("Incorrect redis module version: %s\n", *strp); |
|
|
|
|
|
|
|
|
die("Incorrect redis module version: %s", *strp); |
|
|
redis_mod_verify(dlh); |
|
|
redis_mod_verify(dlh); |
|
|
mc.redis = redis_new_mod(redis_ip, redis_port, redis_db); |
|
|
mc.redis = redis_new_mod(redis_ip, redis_port, redis_db); |
|
|
if (!mc.redis) |
|
|
if (!mc.redis) |
|
|
die("Cannot start up without Redis database\n"); |
|
|
|
|
|
|
|
|
die("Cannot start up without Redis database"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
ctx->m->conf = mc; |
|
|
ctx->m->conf = mc; |
|
|
|
|
|
callmaster_config_init(ctx->m); |
|
|
|
|
|
|
|
|
if (!foreground) |
|
|
if (!foreground) |
|
|
daemonize(); |
|
|
daemonize(); |
|
|
wpidfile(); |
|
|
wpidfile(); |
|
|
|
|
|
|
|
|
if (redis_restore(ctx->m, mc.redis)) |
|
|
if (redis_restore(ctx->m, mc.redis)) |
|
|
die("Refusing to continue without working Redis database\n"); |
|
|
|
|
|
|
|
|
die("Refusing to continue without working Redis database"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static void timer_loop(void *d) { |
|
|
static void timer_loop(void *d) { |
|
|
|