sxt: socket API impl;
This commit is contained in:
		
							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 = 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										191
									
								
								sxt/socket.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								sxt/socket.c
									
									
									
									
									
										Normal file
									
								
							@ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user