mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-cbc.git
synced 2025-11-02 21:23:37 +00:00
CBSP Server improvements
Change-Id: Id4e661ab9281c394eaa82430d49f7e3dfeab3f57
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user