From fb72957594365197e1eb8455130e8a35db647485 Mon Sep 17 00:00:00 2001 From: Andreas Granig Date: Tue, 14 Feb 2012 17:43:41 +0000 Subject: [PATCH] Cleanup regex result indexing and add via branch. - Use defines to index regex results. - Add optional viabranch suffixed to call-id (WIP). --- daemon/call.c | 88 ++++++++++++++++++++++---------------------- daemon/call.h | 3 +- daemon/control.c | 19 ++++------ daemon/control.h | 15 +++++++- daemon/control_udp.c | 55 +++++++++++++-------------- daemon/control_udp.h | 19 +++++++++- 6 files changed, 111 insertions(+), 88 deletions(-) diff --git a/daemon/call.c b/daemon/call.c index 9846878e4..3daee515a 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -1211,34 +1211,34 @@ static struct call *call_get_or_create(const char *callid, struct callmaster *m) return c; } -static int addr_parse_udp(struct stream *st, const char **o) { +static int addr_parse_udp(struct stream *st, const char **out) { u_int32_t ip4; const char *cp; char c; int i; ZERO(*st); - if (o[5] && *o[5]) { - ip4 = inet_addr(o[5]); + if (out[RE_UDP_UL_ADDR4] && *out[RE_UDP_UL_ADDR4]) { + ip4 = inet_addr(out[RE_UDP_UL_ADDR4]); if (ip4 == -1) goto fail; in4_to_6(&st->ip46, ip4); } - else if (o[6] && *o[6]) { - if (inet_pton(AF_INET6, o[6], &st->ip46) != 1) + else if (out[RE_UDP_UL_ADDR6] && *out[RE_UDP_UL_ADDR6]) { + if (inet_pton(AF_INET6, out[RE_UDP_UL_ADDR6], &st->ip46) != 1) goto fail; } else goto fail; - st->port = atoi(o[7]); + st->port = atoi(out[RE_UDP_UL_PORT]); st->mediatype = "unknown"; - if (!st->port && strcmp(o[7], "0")) + if (!st->port && strcmp(out[RE_UDP_UL_PORT], "0")) goto fail; - if (o[3]) { + if (out[RE_UDP_UL_FLAGS]) { i = 0; - for (cp = o[3]; *cp && i < 2; cp++) { + for (cp =out[RE_UDP_UL_FLAGS]; *cp && i < 2; cp++) { c = chrtoupper(*cp); if (c == 'E') st->direction[i++] = DIR_EXTERNAL; @@ -1247,8 +1247,8 @@ static int addr_parse_udp(struct stream *st, const char **o) { } } - if (o[9]) - st->num = atoi(o[9]); + if (out[RE_UDP_UL_NUM]) + st->num = atoi(out[RE_UDP_UL_NUM]); if (!st->num) st->num = 1; @@ -1257,21 +1257,21 @@ fail: return -1; } -char *call_update_udp(const char **o, struct callmaster *m) { +char *call_update_udp(const char **out, struct callmaster *m) { struct call *c; GQueue q = G_QUEUE_INIT; struct stream st; int num; char *ret; - c = call_get_or_create(o[4], m); + c = call_get_or_create(out[RE_UDP_UL_CALLID], m); strdupfree(&c->calling_agent, "UNKNOWN(udp)"); - if (addr_parse_udp(&st, o)) + if (addr_parse_udp(&st, out)) goto fail; g_queue_push_tail(&q, &st); - num = call_streams(c, &q, o[8], 0); + num = call_streams(c, &q, out[RE_UDP_UL_FROMTAG], 0); g_queue_clear(&q); @@ -1279,37 +1279,37 @@ char *call_update_udp(const char **o, struct callmaster *m) { redis_update(c); #endif - ret = streams_print(c->callstreams, 1, (num >= 0) ? 0 : 1, o[1], 1); + ret = streams_print(c->callstreams, 1, (num >= 0) ? 0 : 1, out[RE_UDP_COOKIE], 1); mylog(LOG_INFO, "[%s] Returning to SIP proxy: %s", c->callid, ret); return ret; fail: - mylog(LOG_WARNING, "Failed to parse a media stream: %s/%s:%s", o[5], o[6], o[7]); - asprintf(&ret, "%s E8\n", o[1]); + mylog(LOG_WARNING, "Failed to parse a media stream: %s/%s:%s", out[RE_UDP_UL_ADDR4], out[RE_UDP_UL_ADDR6], out[RE_UDP_UL_PORT]); + asprintf(&ret, "%s E8\n", out[RE_UDP_COOKIE]); return ret; } -char *call_lookup_udp(const char **o, struct callmaster *m) { +char *call_lookup_udp(const char **out, struct callmaster *m) { struct call *c; GQueue q = G_QUEUE_INIT; struct stream st; int num; char *ret; - c = g_hash_table_lookup(m->callhash, o[4]); + c = g_hash_table_lookup(m->callhash, out[RE_UDP_UL_CALLID]); if (!c) { - mylog(LOG_WARNING, "[%s] Got UDP LOOKUP for unknown call-id", o[4]); - asprintf(&ret, "%s 0 " IPF "\n", o[1], IPP(m->ipv4)); + mylog(LOG_WARNING, "[%s] Got UDP LOOKUP for unknown call-id", out[RE_UDP_UL_CALLID]); + asprintf(&ret, "%s 0 " IPF "\n", out[RE_UDP_COOKIE], IPP(m->ipv4)); return ret; } strdupfree(&c->called_agent, "UNKNOWN(udp)"); - if (addr_parse_udp(&st, o)) + if (addr_parse_udp(&st, out)) goto fail; g_queue_push_tail(&q, &st); - num = call_streams(c, &q, o[10], 1); + num = call_streams(c, &q, out[RE_UDP_UL_TOTAG], 1); g_queue_clear(&q); @@ -1317,27 +1317,27 @@ char *call_lookup_udp(const char **o, struct callmaster *m) { redis_update(c); #endif - ret = streams_print(c->callstreams, 1, (num >= 0) ? 1 : 0, o[1], 1); + ret = streams_print(c->callstreams, 1, (num >= 0) ? 1 : 0, out[RE_UDP_COOKIE], 1); mylog(LOG_INFO, "[%s] Returning to SIP proxy: %s", c->callid, ret); return ret; fail: - mylog(LOG_WARNING, "Failed to parse a media stream: %s/%s:%s", o[5], o[6], o[7]); - asprintf(&ret, "%s E8\n", o[1]); + mylog(LOG_WARNING, "Failed to parse a media stream: %s/%s:%s", out[RE_UDP_UL_ADDR4], out[RE_UDP_UL_ADDR6], out[RE_UDP_UL_PORT]); + asprintf(&ret, "%s E8\n", out[RE_UDP_COOKIE]); return ret; } -char *call_request(const char **o, struct callmaster *m) { +char *call_request(const char **out, struct callmaster *m) { struct call *c; GQueue *s; int num; char *ret; - c = call_get_or_create(o[2], m); + c = call_get_or_create(out[RE_TCP_RL_CALLID], m); - strdupfree(&c->calling_agent, o[9] ? : "UNKNOWN"); - info_parse(o[10], &c->infohash); - s = streams_parse(o[3]); + strdupfree(&c->calling_agent, out[RE_TCP_RL_AGENT] ? : "UNKNOWN"); + info_parse(out[RE_TCP_RL_INFO], &c->infohash); + s = streams_parse(out[RE_TCP_RL_STREAMS]); num = call_streams(c, s, g_hash_table_lookup(c->infohash, "fromtag"), 0); streams_free(s); @@ -1350,21 +1350,21 @@ char *call_request(const char **o, struct callmaster *m) { return ret; } -char *call_lookup(const char **o, struct callmaster *m) { +char *call_lookup(const char **out, struct callmaster *m) { struct call *c; GQueue *s; int num; char *ret; - c = g_hash_table_lookup(m->callhash, o[2]); + c = g_hash_table_lookup(m->callhash, out[RE_TCP_RL_CALLID]); if (!c) { - mylog(LOG_WARNING, "[%s] Got LOOKUP for unknown call-id", o[2]); + mylog(LOG_WARNING, "[%s] Got LOOKUP for unknown call-id", out[RE_TCP_RL_CALLID]); return NULL; } - strdupfree(&c->called_agent, o[9] ? : "UNKNOWN"); - info_parse(o[10], &c->infohash); - s = streams_parse(o[3]); + strdupfree(&c->called_agent, out[RE_TCP_RL_AGENT] ? : "UNKNOWN"); + info_parse(out[RE_TCP_RL_INFO], &c->infohash); + s = streams_parse(out[RE_TCP_RL_STREAMS]); num = call_streams(c, s, g_hash_table_lookup(c->infohash, "totag"), 1); streams_free(s); @@ -1377,31 +1377,31 @@ char *call_lookup(const char **o, struct callmaster *m) { return ret; } -char *call_delete_udp(const char **o, struct callmaster *m) { +char *call_delete_udp(const char **out, struct callmaster *m) { struct call *c; char *ret; - c = g_hash_table_lookup(m->callhash, o[13]); + c = g_hash_table_lookup(m->callhash, out[RE_UDP_D_CALLID]); if (!c) goto err; call_destroy(c); - asprintf(&ret, "%s 0\n", o[1]); + asprintf(&ret, "%s 0\n", out[RE_UDP_COOKIE]); goto out; err: - asprintf(&ret, "%s E8\n", o[1]); + asprintf(&ret, "%s E8\n", out[RE_UDP_COOKIE]); goto out; out: return ret; } -void call_delete(const char **o, struct callmaster *m) { +void call_delete(const char **out, struct callmaster *m) { struct call *c; - c = g_hash_table_lookup(m->callhash, o[12]); + c = g_hash_table_lookup(m->callhash, out[RE_TCP_D_CALLID]); if (!c) return; diff --git a/daemon/call.h b/daemon/call.h index a168bc60c..250d2b180 100644 --- a/daemon/call.h +++ b/daemon/call.h @@ -12,7 +12,8 @@ #include #include "xt_MEDIAPROXY.h" - +#include "control.h" +#include "control_udp.h" struct poller; struct control_stream; diff --git a/daemon/control.c b/daemon/control.c index 614862c24..e007c0320 100644 --- a/daemon/control.c +++ b/daemon/control.c @@ -12,14 +12,9 @@ #include "log.h" #include "call.h" - - static pcre *parse_re; static pcre_extra *parse_ree; - - - static void control_stream_closed(int fd, void *p) { struct control_stream *s = p; struct control *c; @@ -78,19 +73,19 @@ static int control_stream_parse(struct control_stream *s, char *line) { pcre_get_substring_list(line, ovec, ret, &out); - if (!strcmp(out[1], "request")) + if (!strcmp(out[RE_TCP_RL_CMD], "request")) output = call_request(out, c->callmaster); - else if (!strcmp(out[1], "lookup")) + else if (!strcmp(out[RE_TCP_RL_CMD], "lookup")) output = call_lookup(out, c->callmaster); - else if (!strcmp(out[11], "delete")) + else if (!strcmp(out[RE_TCP_D_CMD], "delete")) call_delete(out, c->callmaster); - else if (!strcmp(out[14], "status")) + else if (!strcmp(out[RE_TCP_DIV_CMD], "status")) calls_status(c->callmaster, s); - else if (!strcmp(out[14], "build") | !strcmp(out[14], "version")) + else if (!strcmp(out[RE_TCP_DIV_CMD], "build") | !strcmp(out[RE_TCP_DIV_CMD], "version")) streambuf_printf(s->outbuf, "Version: %s\n", MEDIAPROXY_VERSION); - else if (!strcmp(out[14], "controls")) + else if (!strcmp(out[RE_TCP_DIV_CMD], "controls")) control_list(c, s); - else if (!strcmp(out[14], "quit") || !strcmp(out[14], "exit")) + else if (!strcmp(out[RE_TCP_DIV_CMD], "quit") || !strcmp(out[RE_TCP_DIV_CMD], "exit")) ; if (output) { diff --git a/daemon/control.h b/daemon/control.h index 75c62d2f8..0f83119b8 100644 --- a/daemon/control.h +++ b/daemon/control.h @@ -9,7 +9,20 @@ #include #include - +#define RE_TCP_RL_CMD 1 +#define RE_TCP_RL_CALLID 2 +#define RE_TCP_RL_STREAMS 3 +#define RE_TCP_RL_IP 4 +#define RE_TCP_RL_FROMDOM 5 +#define RE_TCP_RL_FROMTYPE 6 +#define RE_TCP_RL_TODOM 7 +#define RE_TCP_RL_TOTYPE 8 +#define RE_TCP_RL_AGENT 9 +#define RE_TCP_RL_INFO 10 +#define RE_TCP_D_CMD 11 +#define RE_TCP_D_CALLID 12 +#define RE_TCP_D_INFO 13 +#define RE_TCP_DIV_CMD 14 struct poller; struct control; diff --git a/daemon/control_udp.c b/daemon/control_udp.c index a9686da6e..c3dc0568a 100644 --- a/daemon/control_udp.c +++ b/daemon/control_udp.c @@ -15,13 +15,6 @@ #include "call.h" - - - - - - - static void control_udp_closed(int fd, void *p) { abort(); } @@ -66,13 +59,13 @@ static void control_udp_incoming(int fd, void *p) { mh.msg_namelen = sizeof(sin); mh.msg_iov = iov; - iov[0].iov_base = (void *) out[1]; - iov[0].iov_len = strlen(out[1]); - if (out[2] && (chrtoupper(out[2][0]) == 'U' || chrtoupper(out[2][0]) == 'L')) { - iov[1].iov_base = (void *) out[4]; - iov[1].iov_len = strlen(out[4]); - iov[2].iov_base = (void *) out[3]; - iov[2].iov_len = strlen(out[3]); + iov[0].iov_base = (void *) out[RE_UDP_COOKIE]; + iov[0].iov_len = strlen(out[RE_UDP_COOKIE]); + if (out[RE_UDP_UL_CMD] && (chrtoupper(out[RE_UDP_UL_CMD][0]) == 'U' || chrtoupper(out[RE_UDP_UL_CMD][0]) == 'L')) { + iov[1].iov_base = (void *) out[RE_UDP_UL_CALLID]; + iov[1].iov_len = strlen(out[RE_UDP_UL_CALLID]); + iov[2].iov_base = (void *) out[RE_UDP_UL_FLAGS]; + iov[2].iov_len = strlen(out[RE_UDP_UL_FLAGS]); iov[3].iov_base = "\n"; iov[3].iov_len = 1; mh.msg_iovlen = 4; @@ -109,40 +102,40 @@ static void control_udp_incoming(int fd, void *p) { } /* XXX better hashing */ - reply = g_hash_table_lookup(u->fresh_cookies, out[1]); + reply = g_hash_table_lookup(u->fresh_cookies, out[RE_UDP_COOKIE]); if (!reply) - reply = g_hash_table_lookup(u->stale_cookies, out[1]); + reply = g_hash_table_lookup(u->stale_cookies, out[RE_UDP_COOKIE]); if (reply) { mylog(LOG_INFO, "Detected command from udp:%s:%u as a duplicate", addr, ntohs(sin.sin6_port)); sendto(fd, reply, strlen(reply), 0, (struct sockaddr *) &sin, sin_len); goto out; } - if (chrtoupper(out[2][0]) == 'U') + if (chrtoupper(out[RE_UDP_UL_CMD][0]) == 'U') reply = call_update_udp(out, u->callmaster); - else if (chrtoupper(out[2][0]) == 'L') + else if (chrtoupper(out[RE_UDP_UL_CMD][0]) == 'L') reply = call_lookup_udp(out, u->callmaster); - else if (chrtoupper(out[11][0]) == 'D') + else if (chrtoupper(out[RE_UDP_D_CMD][0]) == 'D') reply = call_delete_udp(out, u->callmaster); - else if (chrtoupper(out[14][0]) == 'V') { + else if (chrtoupper(out[RE_UDP_V_CMD][0]) == 'V') { ZERO(mh); mh.msg_name = &sin; mh.msg_namelen = sizeof(sin); mh.msg_iov = iov; mh.msg_iovlen = 2; - iov[0].iov_base = (void *) out[1]; - iov[0].iov_len = strlen(out[1]); + iov[0].iov_base = (void *) out[RE_UDP_COOKIE]; + iov[0].iov_len = strlen(out[RE_UDP_COOKIE]); iov[1].iov_base = " "; iov[1].iov_len = 1; - if (chrtoupper(out[15][0]) == 'F') { + if (chrtoupper(out[RE_UDP_V_FLAGS][0]) == 'F') { ret = 0; - if (!strcmp(out[16], "20040107")) + if (!strcmp(out[RE_UDP_V_PARMS], "20040107")) ret = 1; - else if (!strcmp(out[16], "20050322")) + else if (!strcmp(out[RE_UDP_V_PARMS], "20050322")) ret = 1; - else if (!strcmp(out[16], "20060704")) + else if (!strcmp(out[RE_UDP_V_PARMS], "20060704")) ret = 1; iov[2].iov_base = ret ? "1\n" : "0\n"; iov[2].iov_len = 2; @@ -158,7 +151,7 @@ static void control_udp_incoming(int fd, void *p) { if (reply) { sendto(fd, reply, strlen(reply), 0, (struct sockaddr *) &sin, sin_len); - g_hash_table_insert(u->fresh_cookies, g_string_chunk_insert(u->fresh_chunks, out[1]), + g_hash_table_insert(u->fresh_cookies, g_string_chunk_insert(u->fresh_chunks, out[RE_UDP_COOKIE]), g_string_chunk_insert(u->fresh_chunks, reply)); free(reply); } @@ -206,8 +199,12 @@ struct control_udp *control_udp_new(struct poller *p, struct in6_addr ip, u_int1 c->stale_chunks = g_string_chunk_new(4 * 1024); c->oven_time = p->now; c->parse_re = pcre_compile( - /* cookie:1 cmd:2 flags:3 callid:4 addr4:5 addr6:6 port:7 from_tag:8 num:9 to_tag:10 d:11 flags:12 callid:13 v:14 flags:15 parms:16 */ - "^(\\S+)\\s+(?:([ul])(\\S*)\\s+(\\S+)\\s+(?:([\\d.]+)|([\\da-f:]+(?::ffff:[\\d.]+)?))\\s+(\\d+)\\s+(\\S+?);(\\d+)(?:\\s+(\\S+?);\\d+(?:\\s+.*)?)?\r?\n?$|(d)(\\S*)\\s+(\\S+)|(v)(\\S*)(?:\\s+(\\S+))?)", + /* cookie:1 cmd:2 flags:3 callid:4 viabranch:5 addr4:6 addr6:7 port:8 from_tag:9 num:10 to_tag:11 d:12 flags:13 callid:14 viabranch:15 v:16 flags:17 parms:18 */ + "^(\\S+)\\s+(?:([ul])(\\S*)\\s+([^;]+)(?:;(\\S+))?\\s+" \ + "(?:([\\d.]+)|([\\da-f:]+(?::ffff:[\\d.]+)?))" \ + "\\s+(\\d+)\\s+(\\S+?);(\\d+)(?:\\s+(\\S+?);\\d+(?:\\s+.*)?)?\r?\n?$" \ + "|(d)(\\S*)\\s+([^;]+)(?:;(\\S+))?" \ + "|(v)(\\S*)(?:\\s+(\\S+))?)", PCRE_DOLLAR_ENDONLY | PCRE_DOTALL | PCRE_CASELESS, &errptr, &erroff, NULL); c->parse_ree = pcre_study(c->parse_re, 0, &errptr); /* cookie cmd flags callid addr port */ diff --git a/daemon/control_udp.h b/daemon/control_udp.h index b24a8911c..e91a88b67 100644 --- a/daemon/control_udp.h +++ b/daemon/control_udp.h @@ -10,7 +10,24 @@ #include #include - +#define RE_UDP_COOKIE 1 +#define RE_UDP_UL_CMD 2 +#define RE_UDP_UL_FLAGS 3 +#define RE_UDP_UL_CALLID 4 +#define RE_UDP_UL_VIABRANCH 5 +#define RE_UDP_UL_ADDR4 6 +#define RE_UDP_UL_ADDR6 7 +#define RE_UDP_UL_PORT 8 +#define RE_UDP_UL_FROMTAG 9 +#define RE_UDP_UL_NUM 10 +#define RE_UDP_UL_TOTAG 11 +#define RE_UDP_D_CMD 12 +#define RE_UDP_D_FLAGS 13 +#define RE_UDP_D_CALLID 14 +#define RE_UDP_D_VIABRANCH 15 +#define RE_UDP_V_CMD 16 +#define RE_UDP_V_FLAGS 17 +#define RE_UDP_V_PARMS 18 struct poller; struct callmaster;