nat: First go at handling MGCP inside the nat
Listen on the MGCP gateway port and let our protocol stack handle everything for now. We will need to have some more control over things though.
This commit is contained in:
parent
2980442e33
commit
82cb311c4f
|
@ -142,6 +142,7 @@ struct bsc_nat {
|
|||
|
||||
/* MGCP config */
|
||||
struct mgcp_config *mgcp_cfg;
|
||||
struct write_queue mgcp_queue;
|
||||
};
|
||||
|
||||
/* create and init the structures */
|
||||
|
@ -180,5 +181,6 @@ int bsc_write_mgcp(struct bsc_connection *bsc, const u_int8_t *data, unsigned in
|
|||
int bsc_mgcp_assign(struct sccp_connections *, struct msgb *msg);
|
||||
void bsc_mgcp_clear(struct sccp_connections *);
|
||||
void bsc_mgcp_free_endpoints(struct bsc_nat *nat);
|
||||
int bsc_mgcp_init(struct bsc_nat *nat);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int bsc_mgcp_assign(struct sccp_connections *con, struct msgb *msg)
|
||||
{
|
||||
struct tlv_parsed tp;
|
||||
|
@ -74,3 +77,109 @@ void bsc_mgcp_free_endpoints(struct bsc_nat *nat)
|
|||
for (i = 1; i < nat->mgcp_cfg->number_endpoints; ++i)
|
||||
mgcp_free_endp(&nat->mgcp_cfg->endpoints[i]);
|
||||
}
|
||||
|
||||
static int mgcp_do_read(struct bsc_fd *fd)
|
||||
{
|
||||
struct bsc_nat *nat;
|
||||
struct msgb *msg, *resp;
|
||||
int rc;
|
||||
|
||||
msg = msgb_alloc(4096, "MGCP GW Read");
|
||||
if (!msg) {
|
||||
LOGP(DMGCP, LOGL_ERROR, "Failed to create buffer.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
rc = read(fd->fd, msg->data, msg->data_len);
|
||||
if (rc <= 0) {
|
||||
LOGP(DMGCP, LOGL_ERROR, "Failed to read errno: %d\n", errno);
|
||||
msgb_free(msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
nat = fd->data;
|
||||
msg->l2h = msgb_put(msg, rc);
|
||||
resp = mgcp_handle_message(nat->mgcp_cfg, msg);
|
||||
msgb_free(msg);
|
||||
|
||||
/* we do have a direct answer... e.g. AUEP */
|
||||
if (resp) {
|
||||
if (write_queue_enqueue(&nat->mgcp_queue, resp) != 0) {
|
||||
LOGP(DMGCP, LOGL_ERROR, "Failed to enqueue msg.\n");
|
||||
msgb_free(resp);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mgcp_do_write(struct bsc_fd *bfd, struct msgb *msg)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = write(bfd->fd, msg->data, msg->len);
|
||||
|
||||
if (rc != msg->len) {
|
||||
LOGP(DMGCP, LOGL_ERROR, "Failed to write msg to MGCP CallAgent.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int bsc_mgcp_init(struct bsc_nat *nat)
|
||||
{
|
||||
int on;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
if (!nat->mgcp_cfg->call_agent_addr) {
|
||||
LOGP(DMGCP, LOGL_ERROR, "The BSC nat requires the call agent ip to be set.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
nat->mgcp_queue.bfd.fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (nat->mgcp_queue.bfd.fd < 0) {
|
||||
LOGP(DMGCP, LOGL_ERROR, "Failed to create MGCP socket. errno: %d\n", errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
on = 1;
|
||||
setsockopt(nat->mgcp_queue.bfd.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(nat->mgcp_cfg->source_port);
|
||||
inet_aton(nat->mgcp_cfg->source_addr, &addr.sin_addr);
|
||||
|
||||
if (bind(nat->mgcp_queue.bfd.fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||
LOGP(DMGCP, LOGL_ERROR, "Failed to bind. errno: %d\n", errno);
|
||||
close(nat->mgcp_queue.bfd.fd);
|
||||
nat->mgcp_queue.bfd.fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
addr.sin_port = htons(2727);
|
||||
inet_aton(nat->mgcp_cfg->call_agent_addr, &addr.sin_addr);
|
||||
if (connect(nat->mgcp_queue.bfd.fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||
LOGP(DMGCP, LOGL_ERROR, "Failed to connect to: '%s'. errno: %d\n",
|
||||
nat->mgcp_cfg->call_agent_addr, errno);
|
||||
close(nat->mgcp_queue.bfd.fd);
|
||||
nat->mgcp_queue.bfd.fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
write_queue_init(&nat->mgcp_queue, 10);
|
||||
nat->mgcp_queue.bfd.when = BSC_FD_READ;
|
||||
nat->mgcp_queue.bfd.data = nat;
|
||||
nat->mgcp_queue.read_cb = mgcp_do_read;
|
||||
nat->mgcp_queue.write_cb = mgcp_do_write;
|
||||
|
||||
if (bsc_register_fd(&nat->mgcp_queue.bfd) != 0) {
|
||||
LOGP(DMGCP, LOGL_ERROR, "Failed to register MGCP fd.\n");
|
||||
close(nat->mgcp_queue.bfd.fd);
|
||||
nat->mgcp_queue.bfd.fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -754,6 +754,12 @@ int main(int argc, char** argv)
|
|||
/* seed the PRNG */
|
||||
srand(time(NULL));
|
||||
|
||||
/*
|
||||
* Setup the MGCP code..
|
||||
*/
|
||||
if (bsc_mgcp_init(nat) != 0)
|
||||
return -4;
|
||||
|
||||
/* connect to the MSC */
|
||||
msc_con = bsc_msc_create(msc_address, 5000);
|
||||
if (!msc_con) {
|
||||
|
|
Loading…
Reference in New Issue