pespin has uploaded this change for review.

View Change

client: use osmo_stream_cli to transmit data to pcap-server

Similarly to previous work done in osmo-pcap-server, the switch to
osmo_stream doesn't cover the TLS-enabled scenario, since moving TLS
related code to osmo_stream requires significant amount of work and can
be done in a subsequent step.

Related: SYS#7290
Change-Id: I72e8a6ceb4fb1eb70372e13bb139ead0e2bc0860
---
M include/osmo-pcap/osmo_pcap_client.h
M src/Makefile.am
M src/osmo_client_network.c
M src/osmo_client_vty.c
4 files changed, 143 insertions(+), 35 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/osmo-pcap refs/changes/44/39944/1
diff --git a/include/osmo-pcap/osmo_pcap_client.h b/include/osmo-pcap/osmo_pcap_client.h
index 1b66488..fdd59f9 100644
--- a/include/osmo-pcap/osmo_pcap_client.h
+++ b/include/osmo-pcap/osmo_pcap_client.h
@@ -70,7 +70,7 @@
char *srv_ip;
int srv_port;
char *source_ip;
- struct osmo_wqueue wqueue;
+ struct osmo_stream_cli *cli;
struct osmo_timer_list timer;
enum osmo_pcap_protocol protocol;

@@ -87,6 +87,7 @@
unsigned tls_log_level;

struct osmo_tls_session tls_session;
+ struct osmo_wqueue wqueue;

/* back pointer */
struct osmo_pcap_client *client;
diff --git a/src/Makefile.am b/src/Makefile.am
index 504952f..b45bf84 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -26,6 +26,7 @@
$(NULL)

osmo_pcap_client_LDADD = \
+ $(LIBOSMONETIF_LIBS) \
$(LIBOSMOGSM_LIBS) \
$(LIBOSMOVTY_LIBS) \
$(LIBOSMOCORE_LIBS) \
diff --git a/src/osmo_client_network.c b/src/osmo_client_network.c
index abdb7d3..412fe56 100644
--- a/src/osmo_client_network.c
+++ b/src/osmo_client_network.c
@@ -32,6 +32,8 @@
#include <osmocom/core/select.h>
#include <osmocom/core/socket.h>

+#include <osmocom/netif/stream.h>
+
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
@@ -61,13 +63,26 @@

static void write_data(struct osmo_pcap_client_conn *conn, struct msgb *msg)
{
- if (osmo_wqueue_enqueue_quiet(&conn->wqueue, msg) != 0) {
- LOGCONN(conn, LOGL_ERROR, "Failed to enqueue msg (capacity: %u/%u)\n",
- conn->wqueue.current_length, conn->wqueue.max_length);
+ if (conn->tls_on) {
+ if (osmo_wqueue_enqueue_quiet(&conn->wqueue, msg) != 0) {
+ LOGCONN(conn, LOGL_ERROR, "Failed to enqueue msg (capacity: %u/%u)\n",
+ conn->wqueue.current_length, conn->wqueue.max_length);
+ rate_ctr_inc2(conn->client->ctrg, CLIENT_CTR_QERR);
+ msgb_free(msg);
+ }
+ return;
+ }
+
+ if (!conn->cli) {
+ LOGCONN(conn, LOGL_NOTICE, "Failed to enqueue msg (no stream)\n");
rate_ctr_inc2(conn->client->ctrg, CLIENT_CTR_QERR);
msgb_free(msg);
return;
}
+ osmo_stream_cli_send(conn->cli, msg);
+ /* FIXME: osmo_stream_cli_send() doesn't have a rc, hence we cannot never increment on error:
+ * rate_ctr_inc2(conn->client->ctrg, CLIENT_CTR_QERR);
+ */
}

static int read_cb(struct osmo_fd *fd)
@@ -128,22 +143,15 @@
* The write queue needs to work differently for GNUtls. Before we can
* send data we will need to complete handshake.
*/
- if (conn->tls_on) {
- if (!osmo_tls_init_client_session(conn)) {
- lost_connection(conn);
- return -1;
- }
- conn->tls_session.handshake_done = handshake_done_cb;
- conn->tls_session.error = tls_error_cb;
-
- /* fd->data now points somewhere else, stop */
- return 0;
- } else {
- conn->wqueue.bfd.cb = osmo_wqueue_bfd_cb;
- conn->wqueue.bfd.data = conn;
- osmo_wqueue_clear(&conn->wqueue);
- osmo_client_conn_send_link(conn);
+ if (!osmo_tls_init_client_session(conn)) {
+ lost_connection(conn);
+ return -1;
}
+ conn->tls_session.handshake_done = handshake_done_cb;
+ conn->tls_session.error = tls_error_cb;
+
+ /* fd->data now points somewhere else, stop */
+ return 0;
}

if (what & OSMO_FD_READ)
@@ -446,15 +454,13 @@
write_data(conn, msg);
}

-void osmo_client_conn_connect(struct osmo_pcap_client_conn *conn)
+static void osmo_client_conn_connect_tls(struct osmo_pcap_client_conn *conn)
{
int rc;
uint16_t srv_port;
int sock_type, sock_proto;
unsigned int when;

- osmo_client_conn_disconnect(conn);
-
conn->wqueue.read_cb = read_cb;
conn->wqueue.write_cb = write_cb;
osmo_wqueue_clear(&conn->wqueue);
@@ -490,6 +496,91 @@
rate_ctr_inc2(conn->client->ctrg, CLIENT_CTR_CONNECT);
}

+static int stream_cli_connect_cb(struct osmo_stream_cli *cli)
+{
+ struct osmo_pcap_client_conn *conn = osmo_stream_cli_get_data(cli);
+ osmo_client_conn_send_link(conn);
+ return 0;
+}
+
+static int stream_cli_disconnect_cb(struct osmo_stream_cli *cli)
+{
+ struct osmo_pcap_client_conn *conn = osmo_stream_cli_get_data(cli);
+ lost_connection(conn);
+ return 0;
+}
+
+static int stream_cli_read_cb(struct osmo_stream_cli *cli, int res, struct msgb *msg)
+{
+ struct osmo_pcap_client_conn *conn = osmo_stream_cli_get_data(cli);
+
+ msgb_free(msg);
+ if (res <= 0) {
+ LOGCONN(conn, LOGL_ERROR, "Lost connection on read\n");
+ lost_connection(conn);
+ }
+ return 0;
+}
+
+void osmo_client_conn_connect(struct osmo_pcap_client_conn *conn)
+{
+ uint16_t srv_port;
+ int sock_type, sock_proto;
+ struct osmo_stream_cli *cli;
+
+ osmo_client_conn_disconnect(conn);
+
+ /* We still don't support the tls layer through osmo_stream... */
+ if (conn->tls_on) {
+ osmo_client_conn_connect_tls(conn);
+ return;
+ }
+
+ switch (conn->protocol) {
+ case PROTOCOL_OSMOPCAP:
+ srv_port = conn->srv_port;
+ sock_type = SOCK_STREAM;
+ sock_proto = IPPROTO_TCP;
+ break;
+ case PROTOCOL_IPIP:
+ srv_port = 0;
+ sock_type = SOCK_RAW;
+ sock_proto = IPPROTO_IPIP;
+ break;
+ default:
+ OSMO_ASSERT(0);
+ break;
+ }
+
+ OSMO_ASSERT(!conn->cli);
+ conn->cli = cli = osmo_stream_cli_create(conn);
+ osmo_stream_cli_set_name(cli, conn->name);
+ osmo_stream_cli_set_data(cli, conn);
+ osmo_stream_cli_set_type(cli, sock_type);
+ osmo_stream_cli_set_proto(cli, sock_proto);
+ osmo_stream_cli_set_local_addr(cli, conn->source_ip);
+ osmo_stream_cli_set_local_port(cli, 0);
+ osmo_stream_cli_set_addr(cli, conn->srv_ip);
+ osmo_stream_cli_set_port(cli, srv_port);
+ osmo_stream_cli_set_nodelay(cli, true);
+ osmo_stream_cli_set_tx_queue_max_length(cli, conn->wqueue.max_length);
+
+ /* Reconnect is handled by upper layers: */
+ osmo_stream_cli_set_reconnect_timeout(cli, -1);
+ osmo_stream_cli_set_connect_cb(cli, stream_cli_connect_cb);
+ osmo_stream_cli_set_disconnect_cb(cli, stream_cli_disconnect_cb);
+ osmo_stream_cli_set_read_cb2(cli, stream_cli_read_cb);
+
+ if (osmo_stream_cli_open(cli)) {
+ LOGCONN(conn, LOGL_ERROR, "cannot open OML BTS link: %s\n", strerror(errno));
+ conn->cli = NULL;
+ osmo_stream_cli_destroy(cli);
+ return;
+ }
+
+ rate_ctr_inc2(conn->client->ctrg, CLIENT_CTR_CONNECT);
+}
+
void osmo_client_conn_reconnect(struct osmo_pcap_client_conn *conn)
{
lost_connection(conn);
@@ -497,12 +588,20 @@

void osmo_client_conn_disconnect(struct osmo_pcap_client_conn *conn)
{
- if (conn->wqueue.bfd.fd >= 0) {
- osmo_tls_release(&conn->tls_session);
- osmo_fd_unregister(&conn->wqueue.bfd);
- close(conn->wqueue.bfd.fd);
- conn->wqueue.bfd.fd = -1;
- }
-
osmo_timer_del(&conn->timer);
+
+ if (conn->tls_on) {
+ if (conn->wqueue.bfd.fd >= 0) {
+ osmo_tls_release(&conn->tls_session);
+ osmo_fd_unregister(&conn->wqueue.bfd);
+ close(conn->wqueue.bfd.fd);
+ conn->wqueue.bfd.fd = -1;
+ }
+ } else {
+ if (conn->cli) {
+ struct osmo_stream_cli *cli = conn->cli;
+ conn->cli = NULL;
+ osmo_stream_cli_destroy(cli);
+ }
+ }
}
diff --git a/src/osmo_client_vty.c b/src/osmo_client_vty.c
index 1824324..127e52f 100644
--- a/src/osmo_client_vty.c
+++ b/src/osmo_client_vty.c
@@ -25,6 +25,7 @@
#include <osmo-pcap/common.h>

#include <osmocom/core/talloc.h>
+#include <osmocom/netif/stream.h>

#include <stdlib.h>

@@ -262,12 +263,12 @@
{
struct osmo_pcap_client_conn *conn = get_conn(vty);

- if (!conn->tls_on) {
- if (conn->wqueue.bfd.fd >= 0)
- osmo_client_conn_reconnect(conn);
- }
+ if (conn->tls_on)
+ return CMD_SUCCESS;

+ osmo_client_conn_disconnect(conn);
conn->tls_on = true;
+ osmo_client_conn_connect(conn);
return CMD_SUCCESS;
}

@@ -278,10 +279,12 @@
{
struct osmo_pcap_client_conn *conn = get_conn(vty);

- if (conn->tls_on)
- osmo_client_conn_reconnect(conn);
+ if (!conn->tls_on)
+ return CMD_SUCCESS;

+ osmo_client_conn_disconnect(conn);
conn->tls_on = false;
+ osmo_client_conn_connect(conn);
return CMD_SUCCESS;
}

@@ -568,6 +571,10 @@
struct osmo_pcap_client_conn *conn = get_conn(vty);

conn->wqueue.max_length = atoi(argv[0]);
+ /* Apply on conn immediately if already created: */
+ if (conn->cli)
+ osmo_stream_cli_set_tx_queue_max_length(conn->cli, conn->wqueue.max_length);
+
return CMD_SUCCESS;
}


To view, visit change 39944. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: newchange
Gerrit-Project: osmo-pcap
Gerrit-Branch: master
Gerrit-Change-Id: I72e8a6ceb4fb1eb70372e13bb139ead0e2bc0860
Gerrit-Change-Number: 39944
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin@sysmocom.de>