nat: Switch downstream over to the write queue
This commit is contained in:
parent
097c82b2bc
commit
6958065f85
|
@ -58,7 +58,7 @@ static struct bsc_fd bsc_listen;
|
||||||
|
|
||||||
|
|
||||||
static struct bsc_nat *nat;
|
static struct bsc_nat *nat;
|
||||||
static int bsc_write(struct bsc_connection *bsc, const u_int8_t *data, unsigned int length);
|
static void bsc_write(struct bsc_connection *bsc, const u_int8_t *data, unsigned int length);
|
||||||
|
|
||||||
static struct bsc_nat *bsc_nat_alloc(void)
|
static struct bsc_nat *bsc_nat_alloc(void)
|
||||||
{
|
{
|
||||||
|
@ -126,7 +126,7 @@ int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int send_reset_ack(struct bsc_connection *bsc)
|
static void send_reset_ack(struct bsc_connection *bsc)
|
||||||
{
|
{
|
||||||
static const u_int8_t gsm_reset_ack[] = {
|
static const u_int8_t gsm_reset_ack[] = {
|
||||||
0x00, 0x13, 0xfd,
|
0x00, 0x13, 0xfd,
|
||||||
|
@ -135,19 +135,19 @@ static int send_reset_ack(struct bsc_connection *bsc)
|
||||||
0x00, 0x01, 0x31,
|
0x00, 0x01, 0x31,
|
||||||
};
|
};
|
||||||
|
|
||||||
return bsc_write(bsc, gsm_reset_ack, sizeof(gsm_reset_ack));
|
bsc_write(bsc, gsm_reset_ack, sizeof(gsm_reset_ack));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int send_id_ack(struct bsc_connection *bsc)
|
static void send_id_ack(struct bsc_connection *bsc)
|
||||||
{
|
{
|
||||||
static const u_int8_t id_ack[] = {
|
static const u_int8_t id_ack[] = {
|
||||||
0, 1, IPAC_PROTO_IPACCESS, IPAC_MSGT_ID_ACK
|
0, 1, IPAC_PROTO_IPACCESS, IPAC_MSGT_ID_ACK
|
||||||
};
|
};
|
||||||
|
|
||||||
return bsc_write(bsc, id_ack, sizeof(id_ack));
|
bsc_write(bsc, id_ack, sizeof(id_ack));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int send_id_req(struct bsc_connection *bsc)
|
static void send_id_req(struct bsc_connection *bsc)
|
||||||
{
|
{
|
||||||
static const u_int8_t id_req[] = {
|
static const u_int8_t id_req[] = {
|
||||||
0, 17, IPAC_PROTO_IPACCESS, IPAC_MSGT_ID_GET,
|
0, 17, IPAC_PROTO_IPACCESS, IPAC_MSGT_ID_GET,
|
||||||
|
@ -161,7 +161,7 @@ static int send_id_req(struct bsc_connection *bsc)
|
||||||
0x01, IPAC_IDTAG_SERNR,
|
0x01, IPAC_IDTAG_SERNR,
|
||||||
};
|
};
|
||||||
|
|
||||||
return bsc_write(bsc, id_req, sizeof(id_req));
|
bsc_write(bsc, id_req, sizeof(id_req));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -296,16 +296,36 @@ static void initialize_msc_if_needed()
|
||||||
/* do we need to send a GSM 08.08 message here? */
|
/* do we need to send a GSM 08.08 message here? */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bsc_write(struct bsc_connection *bsc, const u_int8_t *data, unsigned int length)
|
/*
|
||||||
|
* Currently we are lacking refcounting so we need to copy each message.
|
||||||
|
*/
|
||||||
|
static void bsc_write(struct bsc_connection *bsc, const u_int8_t *data, unsigned int length)
|
||||||
{
|
{
|
||||||
return write(bsc->write_queue.bfd.fd, data, length);
|
struct msgb *msg;
|
||||||
|
|
||||||
|
if (length > 4096) {
|
||||||
|
LOGP(DINP, LOGL_ERROR, "Can not send message of that size.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg = msgb_alloc(4096, "to-bsc");
|
||||||
|
if (!msg) {
|
||||||
|
LOGP(DINP, LOGL_ERROR, "Failed to allocate memory for BSC msg.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
msgb_put(msg, length);
|
||||||
|
memcpy(msg->data, data, length);
|
||||||
|
if (write_queue_enqueue(&bsc->write_queue, msg) != 0) {
|
||||||
|
LOGP(DINP, LOGL_ERROR, "Failed to enqueue the write.\n");
|
||||||
|
msgb_free(msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int forward_sccp_to_bts(struct msgb *msg)
|
static int forward_sccp_to_bts(struct msgb *msg)
|
||||||
{
|
{
|
||||||
struct bsc_connection *bsc = NULL;
|
struct bsc_connection *bsc = NULL;
|
||||||
struct bsc_nat_parsed *parsed;
|
struct bsc_nat_parsed *parsed;
|
||||||
int rc;
|
|
||||||
|
|
||||||
/* filter, drop, patch the message? */
|
/* filter, drop, patch the message? */
|
||||||
parsed = bsc_nat_parse(msg);
|
parsed = bsc_nat_parse(msg);
|
||||||
|
@ -346,7 +366,8 @@ static int forward_sccp_to_bts(struct msgb *msg)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bsc_write(bsc, msg->data, msg->len);
|
bsc_write(bsc, msg->data, msg->len);
|
||||||
|
return 0;
|
||||||
|
|
||||||
send_to_all:
|
send_to_all:
|
||||||
/*
|
/*
|
||||||
|
@ -380,10 +401,7 @@ send_to_all:
|
||||||
if (!bsc->authenticated || _lac != bsc->lac)
|
if (!bsc->authenticated || _lac != bsc->lac)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
rc = bsc_write(bsc, msg->data, msg->len);
|
bsc_write(bsc, msg->data, msg->len);
|
||||||
if (rc < msg->len)
|
|
||||||
LOGP(DNAT, LOGL_ERROR,
|
|
||||||
"Failed to write message to BTS: %d\n", rc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,11 +412,7 @@ send_to_all:
|
||||||
if (!bsc->authenticated)
|
if (!bsc->authenticated)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
rc = bsc_write(bsc, msg->data, msg->len);
|
bsc_write(bsc, msg->data, msg->len);
|
||||||
|
|
||||||
/* try the next one */
|
|
||||||
if (rc < msg->len)
|
|
||||||
LOGP(DNAT, LOGL_ERROR, "Failed to write message to BTS: %d\n", rc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
@ -619,6 +633,17 @@ static int ipaccess_bsc_read_cb(struct bsc_fd *bfd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ipaccess_bsc_write_cb(struct bsc_fd *bfd, struct msgb *msg)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = write(bfd->fd, msg->data, msg->len);
|
||||||
|
if (rc != msg->len)
|
||||||
|
LOGP(DNAT, LOGL_ERROR, "Failed to write message to the BSC.\n");
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static int ipaccess_listen_bsc_cb(struct bsc_fd *bfd, unsigned int what)
|
static int ipaccess_listen_bsc_cb(struct bsc_fd *bfd, unsigned int what)
|
||||||
{
|
{
|
||||||
struct bsc_connection *bsc;
|
struct bsc_connection *bsc;
|
||||||
|
@ -653,6 +678,7 @@ static int ipaccess_listen_bsc_cb(struct bsc_fd *bfd, unsigned int what)
|
||||||
bsc->write_queue.bfd.data = bsc;
|
bsc->write_queue.bfd.data = bsc;
|
||||||
bsc->write_queue.bfd.fd = ret;
|
bsc->write_queue.bfd.fd = ret;
|
||||||
bsc->write_queue.read_cb = ipaccess_bsc_read_cb;
|
bsc->write_queue.read_cb = ipaccess_bsc_read_cb;
|
||||||
|
bsc->write_queue.write_cb = ipaccess_bsc_write_cb;
|
||||||
bsc->write_queue.bfd.when = BSC_FD_READ;
|
bsc->write_queue.bfd.when = BSC_FD_READ;
|
||||||
if (bsc_register_fd(&bsc->write_queue.bfd) < 0) {
|
if (bsc_register_fd(&bsc->write_queue.bfd) < 0) {
|
||||||
LOGP(DNAT, LOGL_ERROR, "Failed to register BSC fd.\n");
|
LOGP(DNAT, LOGL_ERROR, "Failed to register BSC fd.\n");
|
||||||
|
|
Loading…
Reference in New Issue