l2tp_socket: handle unix sockets using wqueue

This commit is contained in:
Alexander Couzens 2016-10-31 22:27:17 +01:00 committed by Harald Welte
parent b0688440f0
commit 5b97a7ab47
2 changed files with 134 additions and 0 deletions

113
siu/l2tp/l2tpd_socket.c Normal file
View File

@ -0,0 +1,113 @@
#include <errno.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <osmocom/core/write_queue.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/loggingrb.h>
#include <osmocom/core/socket.h>
#include "l2tpd_socket.h"
/* accept a new connection */
static int mncc_sock_accept(struct osmo_fd *bfd, unsigned int flags)
{
struct l2tp_socket_state *state = container_of(bfd, struct l2tp_socket_state, listen_bfd);
struct osmo_fd *conn_bfd = &state->wqueue.bfd;
struct sockaddr_un un_addr;
socklen_t len;
int rc;
len = sizeof(un_addr);
rc = accept(bfd->fd, (struct sockaddr *) &un_addr, &len);
if (rc < 0) {
LOGP(state->log_class, LOGL_ERROR, "Failed to accept a new connection\n");
return -1;
}
if (conn_bfd->fd >= 0) {
LOGP(state->log_class, LOGL_NOTICE, "There is already one connection to the socket\n");
osmo_fd_unregister(conn_bfd);
close(conn_bfd->fd);
return 0;
}
conn_bfd->fd = rc;
conn_bfd->when = BSC_FD_READ | BSC_FD_WRITE;
if (osmo_fd_register(conn_bfd) != 0) {
LOGP(state->log_class, LOGL_ERROR, "Failed to register new connection fd\n");
close(conn_bfd->fd);
conn_bfd->fd = -1;
return -1;
}
LOGP(state->log_class, LOGL_NOTICE, "MNCC Socket has connection with external "
"call control application\n");
return 0;
}
void l2tp_set_read_callback(struct l2tp_socket_state *state, int (*read_cb)(struct osmo_fd *fd))
{
state->wqueue.read_cb = read_cb;
}
void l2tp_set_write_callback(struct l2tp_socket_state *state, int (*write_cb)(struct osmo_fd *fd, struct msgb *msg))
{
state->wqueue.write_cb = write_cb;
}
/*!
* \brief l2tp_enqueue_data
* \param sock
* \return 0 on success
*/
int l2tp_socket_enqueue(struct l2tp_socket_state *state, struct msgb *msg)
{
return osmo_wqueue_enqueue(&state->wqueue, msg);
}
/*!
* \brief l2tp_socket_init
* \param sock
* \param sock_path
* \return 0 on success
*/
int l2tp_socket_init(struct l2tp_socket_state *state, const char *sock_path, int queue_len)
{
struct osmo_fd *bfd;
int rc;
osmo_wqueue_init(&state->wqueue, queue_len);
state->wqueue.bfd.fd = -1;
bfd = &state->listen_bfd;
bfd->fd = osmo_sock_unix_init(SOCK_SEQPACKET, 0, sock_path,
OSMO_SOCK_F_BIND);
if (bfd->fd < 0) {
LOGP(state->log_class, LOGL_ERROR, "Could not create unix socket: %s: %s\n",
sock_path, strerror(errno));
talloc_free(state);
return -1;
}
bfd->when = BSC_FD_READ;
bfd->cb = mncc_sock_accept;
rc = osmo_fd_register(bfd);
if (rc < 0) {
LOGP(state->log_class, LOGL_ERROR, "Could not register listen fd: %d\n", rc);
close(bfd->fd);
talloc_free(state);
return rc;
}
LOGP(state->log_class, LOGL_NOTICE, "MNCC socket at %s\n", sock_path);
return 0;
}

21
siu/l2tp/l2tpd_socket.h Normal file
View File

@ -0,0 +1,21 @@
#pragma once
#include <osmocom/core/write_queue.h>
/*!
* \brief The socket_state struct represents a unix socket
*/
struct l2tp_socket_state {
/*! write queue of our data socket */
struct osmo_wqueue wqueue;
/*! \brief listen_bfd listening socket*/
struct osmo_fd listen_bfd;
int log_class;
};
int l2tp_socket_init(struct l2tp_socket_state *state, const char *sock_path, int queue_len);
int l2tp_socket_enqueue(struct l2tp_socket_state *state, struct msgb *msg);
void l2tp_set_read_callback(struct l2tp_socket_state *state, int (*read_cb)(struct osmo_fd *fd));
void l2tp_set_write_callback(struct l2tp_socket_state *state, int (*write_cb)(struct osmo_fd *fd, struct msgb *msg));