Browse Source

Cleanup regex result indexing and add via branch.

- Use defines to index regex results.
- Add optional viabranch suffixed to call-id (WIP).
git.mgm/mediaproxy-ng/2.0
Andreas Granig 14 years ago
parent
commit
fb72957594
6 changed files with 111 additions and 88 deletions
  1. +44
    -44
      daemon/call.c
  2. +2
    -1
      daemon/call.h
  3. +7
    -12
      daemon/control.c
  4. +14
    -1
      daemon/control.h
  5. +26
    -29
      daemon/control_udp.c
  6. +18
    -1
      daemon/control_udp.h

+ 44
- 44
daemon/call.c View File

@ -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;


+ 2
- 1
daemon/call.h View File

@ -12,7 +12,8 @@
#include <time.h>
#include "xt_MEDIAPROXY.h"
#include "control.h"
#include "control_udp.h"
struct poller;
struct control_stream;


+ 7
- 12
daemon/control.c View File

@ -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) {


+ 14
- 1
daemon/control.h View File

@ -9,7 +9,20 @@
#include <netinet/ip.h>
#include <glib.h>
#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;


+ 26
- 29
daemon/control_udp.c View File

@ -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 */


+ 18
- 1
daemon/control_udp.h View File

@ -10,7 +10,24 @@
#include <time.h>
#include <netinet/in.h>
#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;


Loading…
Cancel
Save