From 0f3d787b19881c5d489ba476d1e5895df4f77084 Mon Sep 17 00:00:00 2001 From: Eugene Crosser Date: Tue, 12 Mar 2019 00:44:37 +0100 Subject: [PATCH] initial code for the socket --- .gitignore | 1 + include/psmb.h | 3 +- src/psmb_priv.h | 26 ++++++++++++-- src/psmb_socket.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 .gitignore create mode 100644 src/psmb_socket.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.o diff --git a/include/psmb.h b/include/psmb.h index e975de4..4b92756 100644 --- a/include/psmb.h +++ b/include/psmb.h @@ -10,7 +10,8 @@ psmb_ctx_t *psmb_new(void); psmb_ctx_t *psmb_new_mm(void *(*malloc)(size_t size), void (*free)(void *ptr), void *(*realloc)(void *ptr, size_t size)); -psmb_result_t psmb_set_pmtu(psmb_ctx_t *ctx, int pmtu); +psmb_result_t psmb_set_pmtu(psmb_ctx_t *ctx, unsigned int pmtu); +psmb_result_t psmb_set_port(psmb_ctx_t *ctx, unsigned short pmtu); psmb_result_t psmb_open(psmb_ctx_t *ctx); void psmb_destroy(psmb_ctx_t *ctx); int psmb_getfd(psmb_ctx_t *ctx); diff --git a/src/psmb_priv.h b/src/psmb_priv.h index 9b57d39..246ad3c 100644 --- a/src/psmb_priv.h +++ b/src/psmb_priv.h @@ -1,14 +1,36 @@ #ifndef _PSMB_PRIV_H #include +#include -struct _psmb_ctx psmb_ctx_t { +#define PSMB_OK 0 +#define PSMB_ERROR 1 +#define PSMB_NEED_WRITE 2 + +#define PSMB_DEFAULT_PORT 5313 +#define PSMB_DEFAULT_PMTU 1452 + +struct _ucaddr { + struct sockaddr_in6 addr; +}; + +struct _msg { + struct _ucaddr peeraddr; + char *channel; + size_t chan_size; + void *data; + size_t data_size; +}; + +struct _psmb_ctx { int fd; void *(*malloc)(size_t size); void (*free)(void *ptr); void *(*realloc)(void *ptr, size_t size); + unsigned short port; int pmtu; - /* data here */ + /* subscription set here */ + struct _msg incoming; }; struct _psmb_result { diff --git a/src/psmb_socket.c b/src/psmb_socket.c new file mode 100644 index 0000000..a7c42ef --- /dev/null +++ b/src/psmb_socket.c @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include +#include + +#include +#include "psmb_priv.h" + +psmb_ctx_t *psmb_new(void) +{ + return psmb_new_mm(malloc, free, realloc); +} + +psmb_ctx_t *psmb_new_mm(void *(*malloc)(size_t size), + void (*free)(void *ptr), + void *(*realloc)(void *ptr, size_t size)) +{ + psmb_ctx_t *ctx = (*malloc)(sizeof(psmb_ctx_t)); + if (!ctx) + return NULL; + *ctx = (psmb_ctx_t){ + .fd = -1, + .malloc = malloc, .free = free, .realloc = realloc, + .pmtu = PSMB_DEFAULT_PMTU, .port = PSMB_DEFAULT_PORT}; + return ctx; +} + +psmb_result_t psmb_set_pmtu(psmb_ctx_t *ctx, unsigned int pmtu) +{ + if (ctx->fd == -1) { + ctx->pmtu = pmtu; + return (psmb_result_t){PSMB_OK}; + } else { + errno = EBUSY; + return (psmb_result_t){PSMB_ERROR}; + } +} + +psmb_result_t psmb_set_port(psmb_ctx_t *ctx, unsigned short port) +{ + if (ctx->fd == -1) { + ctx->port = port; + return (psmb_result_t){PSMB_OK}; + } else { + errno = EBUSY; + return (psmb_result_t){PSMB_ERROR}; + } +} + +psmb_result_t psmb_open(psmb_ctx_t *ctx) +{ + unsigned long on = 1; + struct sockaddr_in6 addr = (struct sockaddr_in6){ + .sin6_family = AF_INET6, + .sin6_addr = in6addr_any, + .sin6_port = htons(ctx->port) + }; + + if (ctx->fd != -1) { + errno = EBUSY; + return (psmb_result_t){PSMB_ERROR}; + } + ctx->fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IPV6); + if (ctx->fd == -1) { + return (psmb_result_t){PSMB_ERROR}; + } + if (setsockopt(ctx->fd, SOL_SOCKET, SO_REUSEADDR, + &on, sizeof(on)) < 0) { + close(ctx->fd); + ctx->fd = -1; + return (psmb_result_t){PSMB_ERROR}; + } + if (setsockopt(ctx->fd, IPPROTO_IPV6, IPV6_PKTINFO, + &on, sizeof(on)) < 0) { + close(ctx->fd); + ctx->fd = -1; + return (psmb_result_t){PSMB_ERROR}; + } + if (bind(ctx->fd, (struct sockaddr *)&addr, + sizeof(struct sockaddr)) == -1) { + close(ctx->fd); + ctx->fd = -1; + return (psmb_result_t){PSMB_ERROR}; + } + return (psmb_result_t){PSMB_OK}; +} -- 2.39.2