aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libmgcp
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 /openbsc/src/libmgcp
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.
Diffstat (limited to 'openbsc/src/libmgcp')
-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);