summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Makefile7
-rw-r--r--lib/base.c113
-rw-r--r--lib/blocking.c67
-rw-r--r--lib/blocking.h4
-rw-r--r--lib/libradsec-base.h72
-rw-r--r--lib/libradsec-levent.h9
-rw-r--r--lib/libradsec.h40
-rw-r--r--lib/test-blocking.c62
8 files changed, 312 insertions, 62 deletions
diff --git a/lib/Makefile b/lib/Makefile
new file mode 100644
index 0000000..71112cb
--- /dev/null
+++ b/lib/Makefile
@@ -0,0 +1,7 @@
+blocking.o: blocking.c blocking.h libradsec-base.h libradsec.h
+base.o: base.c libradsec-base.h libradsec.h
+test-blocking: test-blocking.c blocking.o base.o
+ $(CC) -o $@ $^
+
+doc:
+ doxygen
diff --git a/lib/base.c b/lib/base.c
new file mode 100644
index 0000000..38086c0
--- /dev/null
+++ b/lib/base.c
@@ -0,0 +1,113 @@
+#include <sys/socket.h>
+#include <errno.h>
+#include <stdlib.h>
+#include "libradsec-base.h"
+
+static int
+do_connect(int type,
+ const struct sockaddr *addr,
+ socklen_t addrlen)
+{
+ int s;
+
+ s = socket(AF_INET, type, 0); /* FIXME: do AF_INET6 too */
+ if (s >= 0)
+ if (connect(s, addr, addrlen)) {
+ close(s);
+ s = -1;
+ }
+ return s;
+}
+
+int
+rs_connect(const struct rs_config *conf,
+ const struct sockaddr *addr,
+ socklen_t addrlen)
+{
+ switch (conf->conn_type)
+ {
+ case RS_CONN_TYPE_UDP:
+ return do_connect(SOCK_DGRAM, addr, addrlen);
+ case RS_CONN_TYPE_TCP:
+ return do_connect(SOCK_STREAM, addr, addrlen);
+ /* fall thru */
+ case RS_CONN_TYPE_TLS:
+ /* fall thru */
+ case RS_CONN_TYPE_DTLS:
+ /* fall thru */
+ default:
+ errno = ENOSYS;
+ return -1;
+ }
+}
+
+int
+rs_disconnect( const struct rs_config *conf, int fd)
+{
+ switch (conf->conn_type)
+ {
+ case RS_CONN_TYPE_UDP:
+ return close(fd);
+ case RS_CONN_TYPE_TCP:
+ shutdown(fd, SHUT_RDWR);
+ return close(fd);
+ case RS_CONN_TYPE_TLS:
+ /* fall thru */
+ case RS_CONN_TYPE_DTLS:
+ /* fall thru */
+ default:
+ errno = ENOSYS;
+ return -1;
+ }
+}
+
+struct rs_packet *
+rs_packet_new(const struct rs_config *ctx,
+ const uint8_t buf[RS_HEADER_LEN],
+ size_t *count)
+{
+ struct rs_packet *p =
+ (ctx->alloc_scheme.malloc ? ctx->alloc_scheme.malloc : malloc)(20);
+ if (p) {
+ p->code = buf[0];
+ p->id = buf[1];
+ if (count)
+ *count = 256 * buf[2] + buf[3];
+ }
+ return p;
+}
+
+struct rs_packet *
+rs_packet_parse(const struct rs_config *ctx,
+ struct rs_packet *packet,
+ const uint8_t *buf,
+ size_t buflen)
+{
+ if (buflen < 16) {
+ rs_packet_free(ctx, packet);
+ errno = EPROTO;
+ return NULL;
+ }
+ memcpy(packet->auth, buf, 16);
+ /* TODO: copy attributes starting at buf[16]. */
+ return packet;
+}
+
+void
+rs_packet_free(const struct rs_config *ctx,
+ struct rs_packet *packet)
+{
+ (ctx->alloc_scheme.free ? ctx->alloc_scheme.free : free)(packet);
+}
+
+ssize_t
+rs_packet_serialize(const struct rs_packet *packet,
+ uint8_t *buf,
+ size_t buflen)
+{
+ fixme;
+}
+
+/* Local Variables: */
+/* c-file-style: "stroustrup" */
+/* End: */
diff --git a/lib/blocking.c b/lib/blocking.c
new file mode 100644
index 0000000..6ee4ad3
--- /dev/null
+++ b/lib/blocking.c
@@ -0,0 +1,67 @@
+/* Example usage of libradsec-base, using blocking i/o. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+#include "blocking.h"
+
+struct rs_packet *
+next_packet (const struct rs_config *ctx, int fd)
+{
+ uint8_t hdr[RS_HEADER_LEN];
+ uint8_t *buf;
+ size_t len;
+ struct rs_packet *p;
+ ssize_t n;
+
+ /* Read fixed length header. */
+ n = 0;
+ while (n < RS_HEADER_LEN)
+ n += read (fd, hdr, RS_HEADER_LEN - n);
+
+ p = rs_packet_new (ctx, hdr, &len);
+ fprintf (stderr, "DEBUG: len: %d\n", len);
+ if (p)
+ {
+ /* Read the rest of the packet. */
+ buf = malloc (len);
+ if (buf)
+ {
+ n = 0;
+ while (n < len)
+ n += read (fd, buf, len - n);
+ p = rs_packet_parse (ctx, p, buf, len);
+ free (buf);
+ }
+ }
+
+ return p;
+}
+
+int
+send_packet(const struct rs_config *ctx, int fd, struct rs_packet *p)
+{
+ uint8_t *buf = NULL;
+ ssize_t n = -20; /* Arbitrary packet size -- a guess. */
+
+ while (n < 0)
+ {
+ buf = realloc (buf, -n);
+ if (buf == NULL)
+ return -1;
+ n = rs_packet_serialize (p, buf, -n);
+ }
+
+ while (n)
+ {
+ ssize_t count = write (fd, buf, n);
+ if (count == -1)
+ return -1;
+ n -= count;
+ }
+
+ free (buf);
+ rs_packet_free (ctx, p);
+ return 0;
+}
diff --git a/lib/blocking.h b/lib/blocking.h
new file mode 100644
index 0000000..04a07a8
--- /dev/null
+++ b/lib/blocking.h
@@ -0,0 +1,4 @@
+#include "libradsec-base.h"
+
+struct rs_packet *next_packet (const struct rs_config *ctx, int fd);
+int send_packet (const struct rs_config *ctx, int fd, struct rs_packet *p);
diff --git a/lib/libradsec-base.h b/lib/libradsec-base.h
index cb4308d..a972bf2 100644
--- a/lib/libradsec-base.h
+++ b/lib/libradsec-base.h
@@ -1,43 +1,12 @@
-/** @file libradsec-minimal.h
+/** @file libradsec-base.h
@brief Low level API for libradsec. */
/* FIXME: License blurb goes here. */
-#include "libevent.h"
-
-/* Example usage. */
-#if 0
-{
- fd = rs_connect (address, 0, NULL);
- if (!fd)
- /* check errno */ ;
- n = read (fd, buf, buflen);
- struct rs_packet *p = rs_packet_new (buf, buflen, &count);
- if (!p)
- {
- if (count < 0)
- /* check errno */ ;
- else
- /* need another COUNT octets */ ;
- }
- else
- /* next unused octet is at buf+count */
-
- n = rs_packet_serialize (p, buf, buflen);
- if (n < 0)
- /* invalid packet */ ;
- else if (n == 0)
- /* out of buffer space */ ;
- else
- write (fd, buf, n);
-
- if (p)
- rs_packet_free(p);
- if (fd)
- rs_disconnect(fd);
-}
-#endif
-
+#include <unistd.h>
+#include <stdint.h>
+#include <sys/socket.h>
+#include "libradsec.h"
/* Function prototypes. */
@@ -49,9 +18,9 @@
@return A file descriptor or -1 if an error occurred, in which
case errno is set appropriately. */
-int rs_connect(const struct sockaddr_storage *addr,
- enum rs_conn_type type,
- const struct rs_credentials *cred);
+int rs_connect(const struct rs_config *conf,
+ const struct sockaddr *addr,
+ socklen_t addrlen);
/** Disconnect.
@@ -59,11 +28,14 @@ int rs_connect(const struct sockaddr_storage *addr,
@return 0 on success or -1 if an error occurred, in which case
errno is set appropriately. */
-int rs_disconnect(int fd);
+int rs_disconnect(const struct rs_config *conf,
+ int fd);
/** Allocate and initialize a packet from a buffer containing a packet
as seen on the wire. Free the packet using @a rs_packet_free().
+FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
+
@param buf Buffer with on-the-wire data with packet.
@param buflen Number of octets in @a buf.
@@ -71,19 +43,29 @@ int rs_disconnect(int fd);
successful construction of a packet (return !NULL) or number of
octets needed for a complete packet (return NULL).
+FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
+
@return Packet or NULL on error or not enough data in @a buf. If
return value is NULL and @a count is < 0, an error has occurred
and errno is set appropriately. If return value is NULL and @a
count is > 0 it shows the number of bytes needed to complete the
packet. */
-struct rs_packet *rs_packet_new(const uint8_t *buf,
- size_t buflen,
- ssize_t *count);
+struct rs_packet *rs_packet_new(const struct rs_config *ctx,
+ const uint8_t buf[RS_HEADER_LEN],
+ size_t *count);
+
+struct rs_packet *rs_packet_parse(const struct rs_config *ctx,
+ struct rs_packet *packet,
+ const uint8_t *buf,
+ size_t buflen);
/** Free a packet that has been allocated by @a rs_packet_new().
- @param packet Packet to free. */
-void rs_packet_free(struct rs_packet *packet);
+ @param packet Packet to free.
+ FIXME
+*/
+void rs_packet_free(const struct rs_config *ctx,
+ struct rs_packet *packet);
/** Serialize a packet.
diff --git a/lib/libradsec-levent.h b/lib/libradsec-levent.h
index 17e089a..f79816c 100644
--- a/lib/libradsec-levent.h
+++ b/lib/libradsec-levent.h
@@ -1,10 +1,17 @@
-/** @file libradsec-libevent.h
+/** @file libradsec-levent.h
@brief API for libradsec-libevent. */
/* FIXME: License blurb goes here. */
+#include <sys/socket.h>
#include "libradsec.h"
+struct rs_connection {
+ struct rs_config *conf;
+ struct sockaddr_storage addr;
+ char open_flag;
+};
+
typedef void (*rs_conn_connected_cb)(void *user_data /* FIXME: peer? */);
typedef void (*rs_conn_disconnected_cb)(void *user_data /* FIXME: reason? */);
typedef void (*rs_conn_packet_received_cb)(const struct rs_packet *packet,
diff --git a/lib/libradsec.h b/lib/libradsec.h
index 89f9f2f..fd69c58 100644
--- a/lib/libradsec.h
+++ b/lib/libradsec.h
@@ -4,14 +4,19 @@
/* FIXME: License blurb goes here. */
#include <stdint.h>
-#include <sys/socket.h>
-#include "../list.h"
+#include "../list.h" /* FIXME: ../ is not very nice */
+
+#define RS_HEADER_LEN 4
+
/* Data types. */
-struct rs_config {
- /* FIXME: What's in here that's not in struct rs_conn or
- * rs_credentials? */;
+enum rs_conn_type {
+ RS_CONN_TYPE_NONE = 0,
+ RS_CONN_TYPE_UDP,
+ RS_CONN_TYPE_TCP,
+ RS_CONN_TYPE_TLS,
+ RS_CONN_TYPE_DTLS,
};
enum rs_cred_type {
@@ -22,21 +27,24 @@ enum rs_cred_type {
struct rs_credentials {
enum rs_cred_type type;
char *identity;
- char *secret; /* Passphrase or PSK. */
+ char *secret;
};
-enum rs_conn_type {
- RS_CONN_TYPE_NONE = 0,
- RS_CONN_TYPE_UDP,
- RS_CONN_TYPE_TCP,
- RS_CONN_TYPE_TLS,
- RS_CONN_TYPE_DTLS,
+typedef void * (*rs_calloc)(size_t nmemb, size_t size);
+typedef void * (*rs_malloc)(size_t size);
+typedef void (*rs_free)(void *ptr);
+typedef void * (*rs_realloc)(void *ptr, size_t size);
+struct rs_alloc_scheme {
+ rs_calloc calloc;
+ rs_malloc malloc;
+ rs_free free;
+ rs_realloc realloc;
};
-struct rs_conn {
- enum rs_conn_type type;
+
+struct rs_config {
+ enum rs_conn_type conn_type;
struct rs_credentials transport_credentials;
- struct sockaddr_storage addr;
- char open_flag;
+ struct rs_alloc_scheme alloc_scheme;
};
struct rs_attribute {
diff --git a/lib/test-blocking.c b/lib/test-blocking.c
new file mode 100644
index 0000000..641a34f
--- /dev/null
+++ b/lib/test-blocking.c
@@ -0,0 +1,62 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "blocking.h"
+
+int
+f (const struct sockaddr *addr,
+ socklen_t addrlen,
+ int out_fd)
+{
+ int fd = -1;
+ //struct rs_alloc_scheme as = { calloc, malloc, free, realloc };
+ struct rs_config ctx = { RS_CONN_TYPE_TCP, RS_CRED_NONE, NULL };
+ struct rs_packet *p = NULL;
+
+ fd = rs_connect (&ctx, addr, addrlen);
+ if (fd < 0)
+ {
+ perror ("rs_connect");
+ return -1;
+ }
+
+ p = next_packet (&ctx, fd);
+ if (p == NULL)
+ {
+ perror ("next_packet");
+ rs_disconnect (&ctx, fd);
+ return -1;
+ }
+ rs_disconnect (&ctx, fd);
+
+ if (send_packet (&ctx, out_fd, p))
+ {
+ rs_packet_free (&ctx, p);
+ perror ("send_packet");
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+ struct addrinfo *ai;
+ int rc;
+
+ rc = getaddrinfo (argv[1], argv[2], NULL, &ai);
+ if (rc)
+ {
+ if (rc == EAI_SYSTEM)
+ perror ("getaddrinfo");
+ else
+ fprintf (stderr, "getaddrinfo: %s\n", gai_strerror (rc));
+ return -1;
+ }
+
+ return f (ai->ai_addr, ai->ai_addrlen, 1);
+}