CBSP Server improvements

Change-Id: Id4e661ab9281c394eaa82430d49f7e3dfeab3f57
This commit is contained in:
Harald Welte
2019-08-05 22:08:53 +02:00
parent ba6868f4b9
commit bdf74e9a89
4 changed files with 71 additions and 2 deletions

View File

@@ -6,6 +6,7 @@
#include <osmocom/core/utils.h>
#include "cbc_data.h"
#include "cbsp_server.h"
/* remove a peer from the message */
int cbc_message_del_peer(struct cbc_message *cbcmsg, struct cbc_peer *peer)
@@ -49,6 +50,23 @@ struct cbc_peer *cbc_peer_by_name(const char *name)
return NULL;
}
/* look-up of cbc_peer by tuple of (remote host, protocol) */
struct cbc_peer *cbc_peer_by_addr_proto(const char *remote_host, uint16_t remote_port,
enum cbc_peer_protocol proto)
{
struct cbc_peer *peer;
llist_for_each_entry(peer, &g_cbc->peers, list) {
if (!strcasecmp(remote_host, peer->remote_host)) {
if (peer->remote_port == -1)
return peer;
else if (remote_port == peer->remote_port)
return peer;
}
}
return NULL;
}
/* create a new cbc_peer */
struct cbc_peer *cbc_peer_create(const char *name, enum cbc_peer_protocol proto)
{

View File

@@ -19,6 +19,9 @@ struct cbc_peer {
struct llist_head list; /* linked to cbc.peers */
const char *name;
char *remote_host; /* remote IP address in string format */
int remote_port; /* remote port number or -1 for random */
enum cbc_peer_protocol proto;
union {
struct osmo_cbsp_cbc_client *cbsp;
@@ -104,6 +107,7 @@ struct cbc_message {
struct cbc {
struct {
bool permit_unknown_peers;
} config;
struct llist_head messages; /* cbc_message.list */
@@ -111,3 +115,13 @@ struct cbc {
};
extern struct cbc *g_cbc;
int cbc_message_del_peer(struct cbc_message *cbcmsg, struct cbc_peer *peer);
int cbc_message_add_peer(struct cbc_message *cbcmsg, struct cbc_peer *peer);
struct cbc_peer *cbc_peer_by_name(const char *name);
struct cbc_peer *cbc_peer_by_addr_proto(const char *remote_host, uint16_t remote_port,
enum cbc_peer_protocol proto);
struct cbc_peer *cbc_peer_create(const char *name, enum cbc_peer_protocol proto);
void cbc_peer_remove(struct cbc_peer *peer);

View File

@@ -98,6 +98,7 @@ static int cbsp_cbc_closed_cb(struct osmo_stream_srv *conn)
struct osmo_cbsp_cbc_client *client = osmo_stream_srv_get_data(conn);
LOGPCC(client, LOGL_INFO, "connection closed\n");
llist_del(&client->list);
osmo_fsm_inst_term(client->fi, OSMO_FSM_TERM_REQUEST, NULL);
talloc_free(client);
return 0;
}
@@ -107,12 +108,19 @@ static int cbsp_cbc_accept_cb(struct osmo_stream_srv_link *link, int fd)
{
struct osmo_cbsp_cbc *cbc = osmo_stream_srv_link_get_data(link);
struct osmo_cbsp_cbc_client *client = talloc_zero(cbc, struct osmo_cbsp_cbc_client);
char remote_ip[INET6_ADDRSTRLEN], portbuf[6];
int remote_port;
OSMO_ASSERT(client);
remote_ip[0] = '\0';
portbuf[0] = '\0';
osmo_sock_get_ip_and_port(fd, remote_ip, sizeof(remote_ip), portbuf, sizeof(portbuf), false);
remote_port = atoi(portbuf);
client->conn = osmo_stream_srv_create(link, link, fd, cbsp_cbc_read_cb, cbsp_cbc_closed_cb, client);
if (!client->conn) {
LOGP(DCBSP, LOGL_ERROR, "Unable to create stream server for %s\n",
osmo_sock_get_name2(fd));
LOGP(DCBSP, LOGL_ERROR, "Unable to create stream server for %s:%d\n",
remote_ip, remote_port);
talloc_free(client);
return -1;
}
@@ -123,6 +131,24 @@ static int cbsp_cbc_accept_cb(struct osmo_stream_srv_link *link, int fd)
talloc_free(client);
return -1;
}
/* Match client to peer */
client->peer = cbc_peer_by_addr_proto(remote_ip, remote_port, CBC_PEER_PROTO_CBSP);
if (!client->peer) {
if (g_cbc->config.permit_unknown_peers) {
LOGPCC(client, LOGL_INFO, "Accepting unknown CBSP peer %s:%d\n",
remote_ip, remote_port);
client->peer = cbc_peer_create(NULL, CBC_PEER_PROTO_CBSP);
OSMO_ASSERT(client->peer);
} else {
LOGPCC(client, LOGL_NOTICE, "Rejecting unknown CBSP peer %s:%d (not permitted)\n",
remote_ip, remote_port);
osmo_stream_srv_destroy(client->conn);
/* FIXME: further cleanup needed? or does close_cb handle everything? */
return -1;
}
}
LOGPCC(client, LOGL_INFO, "New CBSP client connection\n");
llist_add_tail(&client->list, &cbc->clients);
osmo_fsm_inst_dispatch(client->fi, CBSP_SRV_E_CMD_RESET, NULL);
@@ -145,6 +171,12 @@ void cbsp_cbc_client_tx(struct osmo_cbsp_cbc_client *client, struct osmo_cbsp_de
osmo_stream_srv_send(client->conn, msg);
}
void cbsp_cbc_client_close(struct osmo_cbsp_cbc_client *client)
{
osmo_stream_srv_destroy(client->conn);
/* FIXME: do we need to unlink/free the client? */
}
/* initialize the CBC-side CBSP server */
struct osmo_cbsp_cbc *cbsp_cbc_create(void *ctx, const char *bind_ip, int bind_port,
int (*rx_cb)(struct osmo_cbsp_cbc_client *client,

View File

@@ -3,6 +3,8 @@
#include <osmocom/gsm/cbsp.h>
#include <osmocom/netif/stream.h>
#include "cbc_data.h"
#define LOGPCC(client, level, fmt, args...) \
LOGP(DCBSP, level, "%s: " fmt, cbsp_cbc_client_name(client), ## args)
@@ -31,10 +33,13 @@ struct osmo_cbsp_cbc_client {
struct msgb *rx_msg;
struct osmo_fsm_inst *fi;
struct cbc_peer *peer;
};
const char *cbsp_cbc_client_name(const struct osmo_cbsp_cbc_client *client);
void cbsp_cbc_client_tx(struct osmo_cbsp_cbc_client *client, struct osmo_cbsp_decoded *cbsp);
void cbsp_cbc_client_close(struct osmo_cbsp_cbc_client *client);
struct osmo_cbsp_cbc *cbsp_cbc_create(void *ctx, const char *bind_ip, int bind_port,
int (*rx_cb)(struct osmo_cbsp_cbc_client *client,
struct osmo_cbsp_decoded *dec));