osmux: Qualify the handle by IPv4 address _and_ port

For our usecase several different systems might be behind the
same firewall so we need to distinguish the remote by more than
the IPv4 address.
This commit is contained in:
Holger Hans Peter Freyther 2014-07-09 00:53:29 +02:00
parent 48a071e366
commit ea7ef38734
1 changed files with 25 additions and 12 deletions

View File

@ -33,20 +33,22 @@ static LLIST_HEAD(osmux_handle_list);
struct osmux_handle {
struct llist_head head;
struct osmux_in_handle *in;
struct in_addr rem_addr;
int rem_port;
};
static void *osmux;
static void osmux_deliver(struct msgb *batch_msg, void *data)
{
struct in_addr *addr = data;
struct osmux_handle *handle = data;
struct sockaddr_in out = {
.sin_family = AF_INET,
.sin_port = htons(OSMUX_PORT),
.sin_port = handle->rem_port,
};
char buf[4096];
memcpy(&out.sin_addr, addr, sizeof(*addr));
memcpy(&out.sin_addr, &handle->rem_addr, sizeof(handle->rem_addr));
osmux_snprintf(buf, sizeof(buf), batch_msg);
LOGP(DMGCP, LOGL_DEBUG, "OSMUX delivering batch to addr=%s: %s\n",
@ -57,16 +59,16 @@ static void osmux_deliver(struct msgb *batch_msg, void *data)
}
static struct osmux_in_handle *
osmux_handle_lookup(struct mgcp_config *cfg, struct in_addr *addr)
osmux_handle_lookup(struct mgcp_config *cfg, struct in_addr *addr, int rem_port)
{
struct osmux_handle *h;
/* Lookup for existing OSMUX handle for this destination address. */
llist_for_each_entry(h, &osmux_handle_list, head) {
if (memcmp(h->in->data, addr, sizeof(struct in_addr)) == 0) {
if (memcmp(&h->rem_addr, addr, sizeof(struct in_addr)) == 0 && h->rem_port == rem_port) {
LOGP(DMGCP, LOGL_DEBUG, "using existing OSMUX handle "
"for addr=%s\n",
inet_ntoa(*addr));
"for addr=%s:%d\n",
inet_ntoa(*addr), ntohs(rem_port));
goto out;
}
}
@ -75,6 +77,8 @@ osmux_handle_lookup(struct mgcp_config *cfg, struct in_addr *addr)
h = talloc_zero(osmux, struct osmux_handle);
if (!h)
return NULL;
h->rem_addr = *addr;
h->rem_port = rem_port;
h->in = talloc_zero(osmux, struct osmux_in_handle);
if (!h->in) {
@ -86,19 +90,19 @@ osmux_handle_lookup(struct mgcp_config *cfg, struct in_addr *addr)
h->in->batch_factor = cfg->osmux_batch;
h->in->deliver = osmux_deliver;
osmux_xfrm_input_init(h->in);
h->in->data = addr;
h->in->data = h;
llist_add(&h->head, &osmux_handle_list);
LOGP(DMGCP, LOGL_DEBUG, "created new OSMUX handle for addr=%s\n",
inet_ntoa(*addr));
LOGP(DMGCP, LOGL_DEBUG, "created new OSMUX handle for addr=%s:%d\n",
inet_ntoa(*addr), ntohs(rem_port));
out:
return h->in;
}
int osmux_xfrm_to_osmux(int type, char *buf, int rc, struct mgcp_endpoint *endp)
{
int ret;
int ret, port;
struct msgb *msg;
struct in_addr *addr;
struct osmux_in_handle *in;
@ -113,9 +117,11 @@ int osmux_xfrm_to_osmux(int type, char *buf, int rc, struct mgcp_endpoint *endp)
switch(type) {
case MGCP_DEST_NET:
addr = &endp->net_end.addr;
port = htons(OSMUX_PORT);
break;
case MGCP_DEST_BTS:
addr = &endp->bts_end.addr;
port = endp->bts_end.rtp_port;
break;
default:
/* Should not ever happen */
@ -125,7 +131,7 @@ int osmux_xfrm_to_osmux(int type, char *buf, int rc, struct mgcp_endpoint *endp)
}
/* Lookup for osmux input handle that munches this RTP frame */
in = osmux_handle_lookup(endp->cfg, addr);
in = osmux_handle_lookup(endp->cfg, addr, port);
if (!in) {
LOGP(DMGCP, LOGL_ERROR, "No osmux handle, aborting\n");
msgb_free(msg);
@ -336,6 +342,13 @@ int osmux_read_from_bsc_cb(struct osmo_fd *ofd, unsigned int what)
goto out;
}
if (endp->bts_end.rtp_port == 0) {
endp->bts_end.rtp_port = addr.sin_port;
LOGP(DMGCP, LOGL_NOTICE, "0x%x found BTS on endpoint %s:%d\n",
ENDPOINT_NUMBER(endp),
inet_ntoa(addr.sin_addr), htons(addr.sin_port));
}
LOGP(DMGCP, LOGL_DEBUG,
"sending extracted RTP from OSMUX to MSC via endpoint=%u "
"(allocated=%d)\n", ENDPOINT_NUMBER(endp), endp->allocated);