|
|
|
@ -5,7 +5,7 @@ |
|
|
|
#include <unistd.h> |
|
|
|
#include <stdlib.h> |
|
|
|
#include <stdio.h> |
|
|
|
#include <pcre.h> |
|
|
|
#include <pcre2.h> |
|
|
|
#include <glib.h> |
|
|
|
#include <time.h> |
|
|
|
#include <netinet/in.h> |
|
|
|
@ -24,15 +24,15 @@ |
|
|
|
static void control_udp_incoming(struct obj *obj, struct udp_buffer *udp_buf) { |
|
|
|
struct control_udp *u = (void *) obj; |
|
|
|
int ret; |
|
|
|
int ovec[100]; |
|
|
|
char **out; |
|
|
|
struct iovec iov[10]; |
|
|
|
unsigned int iovlen; |
|
|
|
str cookie, *reply; |
|
|
|
|
|
|
|
ret = pcre_exec(u->parse_re, u->parse_ree, udp_buf->str.s, udp_buf->str.len, 0, 0, ovec, G_N_ELEMENTS(ovec)); |
|
|
|
pcre2_match_data *md = pcre2_match_data_create(30, NULL); |
|
|
|
ret = pcre2_match(u->parse_re, (PCRE2_SPTR8) udp_buf->str.s, udp_buf->str.len, 0, 0, md, NULL); |
|
|
|
if (ret <= 0) { |
|
|
|
ret = pcre_exec(u->fallback_re, NULL, udp_buf->str.s, udp_buf->str.len, 0, 0, ovec, G_N_ELEMENTS(ovec)); |
|
|
|
ret = pcre2_match(u->fallback_re, (PCRE2_SPTR8) udp_buf->str.s, udp_buf->str.len, 0, 0, md, NULL); |
|
|
|
if (ret <= 0) { |
|
|
|
ilogs(control, LOG_WARNING, "Unable to parse command line from udp:%s: %.*s", udp_buf->addr, STR_FMT(&udp_buf->str)); |
|
|
|
return; |
|
|
|
@ -40,7 +40,7 @@ static void control_udp_incoming(struct obj *obj, struct udp_buffer *udp_buf) { |
|
|
|
|
|
|
|
ilogs(control, LOG_WARNING, "Failed to properly parse UDP command line '%.*s' from %s, using fallback RE", STR_FMT(&udp_buf->str), udp_buf->addr); |
|
|
|
|
|
|
|
pcre_get_substring_list(udp_buf->str.s, ovec, ret, (const char ***) &out); |
|
|
|
pcre2_substring_list_get(md, (PCRE2_UCHAR ***) &out, NULL); |
|
|
|
|
|
|
|
iov[0].iov_base = (void *) out[RE_UDP_COOKIE]; |
|
|
|
iov[0].iov_len = strlen(out[RE_UDP_COOKIE]); |
|
|
|
@ -61,14 +61,15 @@ static void control_udp_incoming(struct obj *obj, struct udp_buffer *udp_buf) { |
|
|
|
|
|
|
|
socket_sendiov(udp_buf->listener, iov, iovlen, &udp_buf->sin); |
|
|
|
|
|
|
|
pcre_free(out); |
|
|
|
pcre2_substring_list_free((PCRE2_SPTR *) out); |
|
|
|
pcre2_match_data_free(md); |
|
|
|
|
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
ilogs(control, LOG_INFO, "Got valid command from udp:%s: %.*s", udp_buf->addr, STR_FMT(&udp_buf->str)); |
|
|
|
|
|
|
|
pcre_get_substring_list(udp_buf->str.s, ovec, ret, (const char ***) &out); |
|
|
|
pcre2_substring_list_get(md, (PCRE2_UCHAR ***) &out, NULL); |
|
|
|
|
|
|
|
str_init(&cookie, (void *) out[RE_UDP_COOKIE]); |
|
|
|
reply = cookie_cache_lookup(&u->cookie_cache, &cookie); |
|
|
|
@ -129,29 +130,29 @@ static void control_udp_incoming(struct obj *obj, struct udp_buffer *udp_buf) { |
|
|
|
cookie_cache_remove(&u->cookie_cache, &cookie); |
|
|
|
|
|
|
|
out: |
|
|
|
pcre_free(out); |
|
|
|
pcre2_substring_list_free((PCRE2_SPTR *) out); |
|
|
|
pcre2_match_data_free(md); |
|
|
|
log_info_pop(); |
|
|
|
} |
|
|
|
|
|
|
|
void control_udp_free(void *p) { |
|
|
|
struct control_udp *u = p; |
|
|
|
pcre_free_study(u->parse_ree); |
|
|
|
pcre_free(u->parse_re); |
|
|
|
pcre_free(u->fallback_re); |
|
|
|
pcre2_code_free(u->parse_re); |
|
|
|
pcre2_code_free(u->fallback_re); |
|
|
|
close_socket(&u->udp_listener); |
|
|
|
cookie_cache_cleanup(&u->cookie_cache); |
|
|
|
} |
|
|
|
|
|
|
|
struct control_udp *control_udp_new(const endpoint_t *ep) { |
|
|
|
struct control_udp *c; |
|
|
|
const char *errptr; |
|
|
|
int erroff; |
|
|
|
PCRE2_SIZE erroff; |
|
|
|
int errcode; |
|
|
|
|
|
|
|
c = obj_alloc0("control_udp", sizeof(*c), control_udp_free); |
|
|
|
|
|
|
|
c->parse_re = pcre_compile( |
|
|
|
c->parse_re = pcre2_compile( |
|
|
|
/* cookie cmd flags callid viabranch:5 */ |
|
|
|
"^(\\S+)\\s+(?:([ul])(\\S*)\\s+([^;]+)(?:;(\\S+))?\\s+" \ |
|
|
|
(PCRE2_SPTR8) "^(\\S+)\\s+(?:([ul])(\\S*)\\s+([^;]+)(?:;(\\S+))?\\s+" \ |
|
|
|
/* addr4 addr6:7 */ |
|
|
|
"(?:([\\d.]+)|([\\da-f:]+(?::ffff:[\\d.]+)?))" \ |
|
|
|
/* port fromtag num totag:11 */ |
|
|
|
@ -160,10 +161,12 @@ struct control_udp *control_udp_new(const endpoint_t *ep) { |
|
|
|
"|([dq])(\\S*)\\s+([^;\\s]+)(?:;(\\S+))?\\s+(\\S+?)(?:;\\d+)?(?:\\s+(\\S+?)(?:;\\d+)?)?\r?\n?$" \ |
|
|
|
/* v flags params:20 */ |
|
|
|
"|(v)(\\S*)(?:\\s+(\\S+))?)", |
|
|
|
PCRE_DOLLAR_ENDONLY | PCRE_DOTALL | PCRE_CASELESS, &errptr, &erroff, NULL); |
|
|
|
c->parse_ree = pcre_study(c->parse_re, 0, &errptr); |
|
|
|
PCRE2_ZERO_TERMINATED, |
|
|
|
PCRE2_DOLLAR_ENDONLY | PCRE2_DOTALL | PCRE2_CASELESS, &errcode, &erroff, NULL); |
|
|
|
/* cookie cmd flags callid addr port */ |
|
|
|
c->fallback_re = pcre_compile("^(\\S+)(?:\\s+(\\S)\\S*\\s+\\S+(\\s+\\S+)(\\s+\\S+))?", PCRE_DOLLAR_ENDONLY | PCRE_DOTALL | PCRE_CASELESS, &errptr, &erroff, NULL); |
|
|
|
c->fallback_re = pcre2_compile((PCRE2_SPTR8) "^(\\S+)(?:\\s+(\\S)\\S*\\s+\\S+(\\s+\\S+)(\\s+\\S+))?", |
|
|
|
PCRE2_ZERO_TERMINATED, |
|
|
|
PCRE2_DOLLAR_ENDONLY | PCRE2_DOTALL | PCRE2_CASELESS, &errcode, &erroff, NULL); |
|
|
|
|
|
|
|
if (!c->parse_re || !c->fallback_re) |
|
|
|
goto fail2; |
|
|
|
|