aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2016-11-08 18:48:57 +0100
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2016-11-09 01:03:59 +0100
commit956c3facf1950e8f84291089972ab8323c75767a (patch)
tree33606e15a6a746e660b594036068f222173c8674
parente3d7c3e1545fcba6d14e2daef08da3400a136a32 (diff)
client: Enable a non-blocking connect to the PCAP server
If we want to have multiple servers we should not block when trying to connect to one of them. Enable non blocking mode and handle the fd specially until it is connected. E.g. on failed connect the read will become readable but fail, otherwise it becomes writable. Clear the write queue to make sure that the link data is sent first. We might be able to introduce a osmo_wqueue_prepend. Change-Id: Iae2bc264d15aa8598beefc194e3b8c4ebe87320a
-rw-r--r--src/osmo_client_network.c56
1 files changed, 38 insertions, 18 deletions
diff --git a/src/osmo_client_network.c b/src/osmo_client_network.c
index d1d39dc..0662934 100644
--- a/src/osmo_client_network.c
+++ b/src/osmo_client_network.c
@@ -107,6 +107,7 @@ static void handshake_done_cb(struct osmo_tls_session *session)
struct osmo_pcap_client_conn *conn;
conn = container_of(session, struct osmo_pcap_client_conn, tls_session);
+ osmo_wqueue_clear(&conn->wqueue);
osmo_client_send_link(conn);
}
@@ -118,6 +119,38 @@ static void tls_error_cb(struct osmo_tls_session *session)
lost_connection(conn);
}
+int conn_cb(struct osmo_fd *fd, unsigned int what)
+{
+ /* finally the socket is connected... continue */
+ if (what & BSC_FD_WRITE) {
+ struct osmo_pcap_client_conn *conn = fd->data;
+ /*
+ * 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_send_link(conn);
+ }
+ }
+
+ if (what & BSC_FD_READ)
+ read_cb(fd);
+ return 0;
+}
+
void osmo_client_send_data(struct osmo_pcap_client_conn *conn,
struct pcap_pkthdr *in_hdr, const uint8_t *data)
{
@@ -198,7 +231,8 @@ void osmo_client_connect(struct osmo_pcap_client_conn *conn)
osmo_wqueue_clear(&conn->wqueue);
fd = osmo_sock_init(AF_INET, SOCK_STREAM, IPPROTO_TCP,
- conn->srv_ip, conn->srv_port, OSMO_SOCK_F_CONNECT);
+ conn->srv_ip, conn->srv_port,
+ OSMO_SOCK_F_CONNECT | OSMO_SOCK_F_NONBLOCK);
if (fd < 0) {
LOGP(DCLIENT, LOGL_ERROR,
"Failed to connect to %s:%d\n",
@@ -216,23 +250,9 @@ void osmo_client_connect(struct osmo_pcap_client_conn *conn)
}
rate_ctr_inc(&conn->client->ctrg->ctr[CLIENT_CTR_CONNECT]);
-
- /*
- * 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;
- }
- conn->tls_session.handshake_done = handshake_done_cb;
- conn->tls_session.error = tls_error_cb;
- } else {
- conn->wqueue.bfd.cb = osmo_wqueue_bfd_cb;
- conn->wqueue.bfd.data = conn;
- osmo_client_send_link(conn);
- }
+ conn->wqueue.bfd.cb = conn_cb;
+ conn->wqueue.bfd.data = conn;
+ conn->wqueue.bfd.when = BSC_FD_READ | BSC_FD_WRITE;
}
void osmo_client_reconnect(struct osmo_pcap_client_conn *conn)