aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/jail_packet.c53
-rw-r--r--src/jail_packet.h12
2 files changed, 54 insertions, 11 deletions
diff --git a/src/jail_packet.c b/src/jail_packet.c
index 4e5bd64..fa19cc5 100644
--- a/src/jail_packet.c
+++ b/src/jail_packet.c
@@ -1,4 +1,6 @@
+#include <string.h>
#include <arpa/inet.h>
+#include <assert.h>
#include "jail_packet.h"
#include "utils.h"
@@ -8,8 +10,8 @@ typedef struct jail_packet {
uint16_t size;
} jail_packet;
-typedef ssize_t (*packet_callback)(jail_packet_ctx *ctx, unsigned char *data,
- size_t siz);
+typedef ssize_t (*packet_callback)(jail_packet_ctx *ctx, event_buf *read_buf,
+ event_buf *write_buf);
typedef struct jail_packet_callback {
uint8_t type;
@@ -17,7 +19,9 @@ typedef struct jail_packet_callback {
} jail_packet_callback;
static ssize_t pkt_header_read(unsigned char *buf, size_t siz);
-static ssize_t pkt_hello(jail_packet_ctx *ctx, unsigned char *data, size_t siz);
+static ssize_t pkt_hello(jail_packet_ctx *ctx, event_buf *read_buf,
+ event_buf *write_buf);
+static int jail_event_loop(event_ctx *ctx, event_buf *buf, void *user_data);
#define PKT_CB(type, cb) \
{ type, cb }
@@ -45,13 +49,48 @@ static ssize_t pkt_header_read(unsigned char *buf, size_t siz)
return pkt->size;
}
-static ssize_t pkt_hello(jail_packet_ctx *ctx, unsigned char *data, size_t siz)
+static ssize_t pkt_hello(jail_packet_ctx *ctx, event_buf *read_buf,
+ event_buf *write_buf)
{
return -1;
}
-int jail_packet_loop(event_ctx *ctx, jail_packet_ctx *pkt_ctx,
- on_data_cb on_data)
+static int jail_event_loop(event_ctx *ctx, event_buf *buf, void *user_data)
{
- return 1;
+ jail_packet_ctx *pkt_ctx = (jail_packet_ctx *) user_data;
+ jail_packet *pkt;
+ event_buf wbuf = { -1, {0}, 0, user_data };
+ ssize_t pkt_siz;
+ off_t pkt_off = 0;
+
+ while (1) {
+ pkt_siz = pkt_header_read((unsigned char *) buf->buf + pkt_off,
+ buf->buf_used);
+ if (pkt_siz < 0)
+ break;
+ pkt = (jail_packet *)(buf->buf + pkt_off);
+
+ if (jpc[pkt->type].pc &&
+ jpc[pkt->type].pc(pkt_ctx, buf, &wbuf) < 0)
+ {
+ pkt_ctx->pstate = JP_INVALID;
+ break;
+ }
+
+ pkt_off += pkt_siz + sizeof *pkt;
+ buf->buf_used -= pkt_off;
+ }
+
+ if (pkt_off)
+ memmove(buf->buf, buf->buf + pkt_off, buf->buf_used);
+
+ return pkt_ctx->pstate != JP_NONE && pkt_ctx->pstate != JP_INVALID;
+}
+
+int jail_packet_loop(event_ctx *ctx, jail_packet_ctx *pkt_ctx)
+{
+ assert(pkt_ctx->on_data && pkt_ctx->user_data);
+ pkt_ctx->pstate = JP_NONE;
+
+ return event_loop(ctx, jail_event_loop, pkt_ctx);
}
diff --git a/src/jail_packet.h b/src/jail_packet.h
index 0fc202d..55016d5 100644
--- a/src/jail_packet.h
+++ b/src/jail_packet.h
@@ -38,19 +38,23 @@
#include "pevent.h"
-#define PKT_INVALID 0x0
-#define PKT_HELLO 0x1
+#define PKT_INVALID 0x0 /* should not happen, otherwise error */
+#define PKT_HELLO 0x1 /* request(PKT_HELLO) -> response(PKT_HELLO) */
+#define PKT_USER 0x2 /* request(PKT_USER) -> response(PKT_USER) */
+#define PKT_PASS 0x3 /* request(PKT_PASS) -> response(PKT_PASS) */
typedef enum jail_packet_state {
JP_NONE, JP_INVALID, JP_HELLO
} jail_packet_state;
typedef struct jail_packet_ctx {
+ int is_server;
jail_packet_state pstate;
+ on_data_cb on_data;
+ void *user_data;
} jail_packet_ctx;
-int jail_packet_loop(event_ctx *ctx, jail_packet_ctx *pkt_ctx,
- on_data_cb on_data);
+int jail_packet_loop(event_ctx *ctx, jail_packet_ctx *pkt_ctx);
#endif