aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-07-09 00:53:29 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-07-22 15:15:13 +0200
commitea7ef387343a6a3ad07d1fbca76d842e0872cf6d (patch)
treec56571d14f24adaaac51330a17b0e46aaec964b3
parent48a071e3665a3e04fd7c341dd28422796682f5f5 (diff)
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.
-rw-r--r--openbsc/src/libmgcp/osmux.c37
1 files changed, 25 insertions, 12 deletions
diff --git a/openbsc/src/libmgcp/osmux.c b/openbsc/src/libmgcp/osmux.c
index ad9c2ee71..b7131833d 100644
--- a/openbsc/src/libmgcp/osmux.c
+++ b/openbsc/src/libmgcp/osmux.c
@@ -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);