aboutsummaryrefslogtreecommitdiff
path: root/src/forward.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/forward.c')
-rw-r--r--src/forward.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/forward.c b/src/forward.c
new file mode 100644
index 0000000..16fec1a
--- /dev/null
+++ b/src/forward.c
@@ -0,0 +1,65 @@
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "forward.h"
+#include "log.h"
+
+
+int fwd_init_ctx(forward_ctx **ctx, init_cb init_fn)
+{
+ assert(ctx || init_fn);
+ if (!*ctx)
+ *ctx = (forward_ctx *) malloc(sizeof(**ctx));
+ assert(*ctx);
+
+ memset(*ctx, 0, sizeof(**ctx));
+ if (init_fn(*ctx))
+ return 1;
+
+ return 0;
+}
+
+int fwd_setup(forward_ctx *ctx, const char *host, const char *port)
+{
+ int s;
+ struct addrinfo *fwd_addr = NULL;
+
+ assert(ctx);
+
+ s = socket_init_in(host, port, &fwd_addr);
+ if (s) {
+ E_GAIERR(s, "Could not initialise forward socket");
+ return 1;
+ }
+ if (!ctx->fwd_cbs.on_listen)
+ return 1;
+ if (ctx->fwd_cbs.on_listen(ctx))
+ return 1;
+ if (socket_connect_in(&ctx->sock, fwd_addr)) {
+ E_STRERR("Could not connect forward socket");
+ return 1;
+ }
+ s = socket_addrtostr_in(&ctx->sock, ctx->host_buf, ctx->service_buf);
+ if (s) {
+ E_GAIERR(s, "Convert forward socket address to string");
+ return 1;
+ }
+ if (socket_close(&ctx->sock)) {
+ E_STRERR("Forward socket close");
+ return 1;
+ }
+
+ return 0;
+}
+
+int fwd_validate_ctx(const forward_ctx *ctx)
+{
+ assert(ctx);
+ assert(ctx->fwd_cbs.on_listen && ctx->fwd_cbs.on_shutdown);
+ assert(ctx->sock.addr_len > 0);
+ assert(strnlen(ctx->host_buf, NI_MAXHOST) > 0);
+ assert(strnlen(ctx->service_buf, NI_MAXSERV) > 0);
+
+ return 0;
+}