sxt: socket API impl;

master
Alexander Vdolainen 8 years ago
parent 5135deef30
commit 82e97bce60

@ -28,11 +28,13 @@ enum {
SXTSOCKET_NIL = 0,
SXTSOCKET_ACTIVE,
SXTSOCKET_DEAD,
SXTSOCKET_CLOSED,
};
#define SXTSCK_RDR (1 << 1)
#define SXTSCK_WRR (1 << 2)
#define SXTSCT_TMO (1 << 3)
#define SXTSCT_ERR (1 << 4)
typedef struct __sxtsocket_type {
uint8_t state;
@ -40,17 +42,18 @@ typedef struct __sxtsocket_type {
} sxtsocket_t;
/* API */
sxtsocket_t *sxtsocket_new();
sxtsocket_t *sxtsocket_new(void);
int sxtsocket_close(sxtsocket_t *);
int sxtsocket_setnb(sxtsocket_t *);
size_t sxtsocket_read(sxtsocket_t *, void *, size_t);
ssize_t sxtsocket_read(sxtsocket_t *, void *, size_t);
size_t sxtsocket_write(sxtsocket_t *, void *, size_t);
ssize_t sxtsocket_write(sxtsocket_t *, void *, size_t);
int sxtsocket_poll(sxtsocket_t **, int, sxtsocket_t **, int, void *);
int sxtsocket_poll(sxtsocket_t **, int, sxtsocket_t **, int, int, int **,
int **);
void sxtsocket_free(sxtsocket_t *);

@ -16,7 +16,8 @@ lib_LTLIBRARIES = libsxt.la
libsxt_la_SOURCES = \
core.c base64.c misc.c safebuffer.c rdb.c ppkp_ops.c \
bcrypt.c blowfish.c ciphers.c lcrypt.c \
fe25519.c ge25519.c sc25519.c ed25519.c
fe25519.c ge25519.c sc25519.c ed25519.c \
socket.c
libsxt_la_LDFLAGS =

@ -0,0 +1,191 @@
/*
* Secure eXtended Message Passing framework
* Secure eXtended Transport layer implementation (libsxt).
*
* socket wrapper
*
* (c) Alexander Vdolainen 2016 <avdolainen@zoho.com>
*
* libsxmp is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libsxmp is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
*
*/
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <string.h>
#include <poll.h>
#include <sxt/errno.h>
#include <sxt/socket.h>
sxtsocket_t *sxtsocket_new(void)
{
sxtsocket_t *s = malloc(sizeof(sxtsocket_t));
if(!s) return NULL;
s->state = SXTSOCKET_NIL;
return s;
}
int sxtsocket_close(sxtsocket_t *s)
{
if(!s) return SXT_EINVAL;
if(s->state == SXTSOCKET_ACTIVE || s->state == SXTSOCKET_DEAD) {
close(s->fd);
s->state = SXTSOCKET_CLOSED;
}
/* in other cases ignore, already closed or never opened */
return SXT_SUCCESS;
}
int sxtsocket_setnb(sxtsocket_t *s)
{
#ifndef WIN32
int fdmode;
#endif
if(!s || s->state != SXTSOCKET_ACTIVE) return SXT_EINVAL;
#ifndef WIN32
fdmode = fcntl(s->fd, F_GETFL, 0);
fdmode |= O_NDELAY;
if(fcntl(s->fd, F_SETFL, fdmode)) return SXT_EIO;
#endif
return SXT_SUCCESS;
}
ssize_t sxtsocket_read(sxtsocket_t *s, void *buf, size_t bufsize)
{
ssize_t rcnt = -1;
if(!s || s->state != SXTSOCKET_ACTIVE) goto __failed;
rcnt = read(s->fd, buf, bufsize);
__failed:
return rcnt;
}
ssize_t sxtsocket_write(sxtsocket_t *s, void *buf, size_t bufsize)
{
ssize_t wcnt = -1;
if(!s || s->state != SXTSOCKET_ACTIVE) goto __failed;
wcnt = write(s->fd, (const void *)buf, bufsize);
__failed:
return wcnt;
}
int sxtsocket_poll(sxtsocket_t **rsck, int rscksz, sxtsocket_t **wsck,
int wscksz, int tm_msec, int **ra, int **wa)
{
int r = 0, i = 0, err = SXTSCT_ERR, c, ii;
struct pollfd *fds = NULL;
int *rr = NULL, *wr = NULL;
if(!rsck || !wsck) return SXTSCT_ERR;
if(!rscksz || !wscksz) return SXTSCT_ERR;
if(!(fds = malloc(sizeof(struct pollfd)*(rscksz + wscksz)))) return SXTSCT_ERR;
else memset(fds, 0, sizeof(struct pollfd)*(rscksz + wscksz));
/* fill and check given values */
for(i = 0; i < rscksz; i++) {
if(rsck[i]->state != SXTSOCKET_ACTIVE) goto __failed;
fds[i].fd = rsck[i]->fd;
fds[i].events = POLLIN | POLLPRI;
}
for(; i < rscksz + wscksz; i++) {
if(wsck[i - rscksz]->state != SXTSOCKET_ACTIVE) goto __failed;
fds[i].fd = wsck[i - rscksz]->fd;
fds[i].events = POLLOUT;
}
r = poll(fds, rscksz + wscksz, tm_msec);
if(!r) {
err = SXTSCT_TMO;
goto __failed;
} else if(r < 0) goto __failed;
for(i = 0, c = 0; i < rscksz; i++) {
if(fds[i].revents) {
if((fds[i].revents & POLLHUP) || (fds[i].revents & POLLERR))
rsck[i]->state = SXTSOCKET_DEAD;
c++;
}
}
if(c) {
if(!(rr = malloc(sizeof(int)*(c + 1)))) {
err = SXTSCT_ERR;
goto __failed;
}
for(i = 0, ii = 0; i < rscksz; i++) {
if(fds[i].revents) {
rr[ii] = i;
ii++;
}
}
rr[ii] = -1;
err = 0;
err |= SXTSCK_RDR;
}
if((r - c) > 0) {
r -= c;
if(!(wr = malloc(sizeof(int)*(r + 1)))) {
err = SXTSCT_ERR;
goto __failed;
}
for(i = rscksz, ii = 0; i < (rscksz + wscksz); i++) {
if(fds[i].revents) {
if((fds[i].revents & POLLHUP) || (fds[i].revents & POLLERR))
wsck[i - rscksz]->state = SXTSOCKET_DEAD;
wr[ii] = i - rscksz;
ii++;
}
}
wr[ii] = -1;
if(err == SXTSCT_ERR) err = 0;
err |= SXTSCK_WRR;
}
r = 0;
__failed:
if(fds) free(fds);
if(r > 0 && err == SXTSCT_ERR) {
if(rr) free(rr);
if(wr) free(wr);
}
return err;
}
void sxtsocket_free(sxtsocket_t *s)
{
if(!s) return;
else sxtsocket_close(s);
free(s);
return;
}
Loading…
Cancel
Save