14687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones/*
24687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones * test-bio.c - BIO layer for testing
34687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones *
44687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones * Copyright (c) 2012 The Chromium Authors. All rights reserved.
54687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones * Use of this source code is governed by a BSD-style license that can be
64687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones * found in the LICENSE file.
74687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones *
84687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones * This is a 'source/sink' BIO which supports synthetic inputs and outputs, and
94687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones * can be used to drive filter BIOs through a state machine. It buffers all
104687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones * output sent to it, which can be retrieved with BIO_test_get_output(), and
114687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones * input sent to it, which is handed back in response to BIO_read() by the
124687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones * filter BIO.
134687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones */
144687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones
154687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones#include <assert.h>
164687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones#include <string.h>
174687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones
18fa765306c820607423e1d6eb526a027a7a5f35dcJacob Appelbaum#include "src/test-bio.h"
19fa765306c820607423e1d6eb526a027a7a5f35dcJacob Appelbaum#include "src/util.h"
204687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones
21b24f342311f93ff61a73ba4628dc173d09c50413Jacob Appelbaumint verbose;
22232fa7e93cd02d176ba2501d8d0e6614b2563ac0Jacob Appelbaumint verbose_debug;
23b24f342311f93ff61a73ba4628dc173d09c50413Jacob Appelbaum
244687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jonesstatic const unsigned int kMagic = 0x5f8d3f15;
254687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones
26c45952f88c568046a02bc0aea793008d8bb37755Will Drewrystruct test_ctx
27c45952f88c568046a02bc0aea793008d8bb37755Will Drewry{
286964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  unsigned int magic;
296964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  unsigned char *out;
306964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  size_t outsz;
316964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  unsigned char *in;
326964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  size_t insz;
334687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones};
344687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones
35c45952f88c568046a02bc0aea793008d8bb37755Will Drewrystatic struct test_ctx *bio_ctx (BIO *b)
364687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones{
376964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  struct test_ctx *ctx = b->ptr;
38c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  assert (ctx->magic == kMagic);
396964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  return ctx;
404687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones}
414687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones
42c45952f88c568046a02bc0aea793008d8bb37755Will Drewrystatic size_t buf_drain (unsigned char **buf, size_t *bufsz,
43c45952f88c568046a02bc0aea793008d8bb37755Will Drewry                         unsigned char *out, size_t outsz)
444687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones{
456964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  if (*bufsz < outsz)
466964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum    outsz = *bufsz;
47c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  memcpy (out, *buf, outsz);
486964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  if (*bufsz > outsz)
49c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    memmove (*buf, *buf + outsz, *bufsz - outsz);
506964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  *bufsz -= outsz;
51c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  *buf = realloc (*buf, *bufsz);
526964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  return outsz;
534687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones}
544687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones
55c45952f88c568046a02bc0aea793008d8bb37755Will Drewrystatic void buf_fill (unsigned char **buf, size_t *bufsz,
56c45952f88c568046a02bc0aea793008d8bb37755Will Drewry                      const unsigned char *in, size_t insz)
574687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones{
58c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  *buf = realloc (*buf, *bufsz + insz);
59c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  memcpy (*buf + *bufsz, in, insz);
606964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  *bufsz += insz;
614687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones}
624687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones
63c45952f88c568046a02bc0aea793008d8bb37755Will Drewryint test_new (BIO *b)
644687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones{
65c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  struct test_ctx *ctx = malloc (sizeof *ctx);
666964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  if (!ctx)
676964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum    return 0;
686964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  ctx->magic = kMagic;
696964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  ctx->in = NULL;
706964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  ctx->insz = 0;
716964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  ctx->out = NULL;
726964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  ctx->outsz = 0;
736964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  b->init = 1;
746964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  b->flags = 0;
756964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  b->ptr = ctx;
766964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  return 1;
774687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones}
784687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones
79c45952f88c568046a02bc0aea793008d8bb37755Will Drewryint test_free (BIO *b)
804687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones{
816964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  struct test_ctx *ctx;
826964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  if (!b || !b->ptr)
836964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum    return 1;
84c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  ctx = bio_ctx (b);
85c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  free (ctx->in);
86c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  free (ctx->out);
876964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  return 1;
884687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones}
894687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones
90c45952f88c568046a02bc0aea793008d8bb37755Will Drewryint test_write (BIO *b, const char *buf, int sz)
914687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones{
92c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  struct test_ctx *ctx = bio_ctx (b);
936964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  if (sz <= 0)
946964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum    return 0;
95c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  buf_fill (&ctx->out, &ctx->outsz, (unsigned char *) buf, sz);
966964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  return sz;
974687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones}
984687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones
99c45952f88c568046a02bc0aea793008d8bb37755Will Drewryint test_read (BIO *b, char *buf, int sz)
1004687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones{
101c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  struct test_ctx *ctx = bio_ctx (b);
1026964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  if (sz <= 0)
1036964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum    return 0;
104c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  return buf_drain (&ctx->in, &ctx->insz, (unsigned char *) buf, sz);
1054687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones}
1064687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones
107c45952f88c568046a02bc0aea793008d8bb37755Will Drewrylong test_ctrl (BIO *b, int cmd, long num, void *ptr)
1084687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones{
1096964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  return 0;
1104687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones}
1114687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones
1124def35436a9e7d8531fb29b1e6e8c511cf556822Gilad Arnoldlong test_callback_ctrl (BIO *b, int cmd, bio_info_cb fp)
1134687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones{
1146964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  return 0;
1154687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones}
1164687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones
117c45952f88c568046a02bc0aea793008d8bb37755Will DrewryBIO_METHOD test_methods =
118c45952f88c568046a02bc0aea793008d8bb37755Will Drewry{
1196964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  BIO_TYPE_SOCKET,
1206964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  "test",
1216964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  test_write,
1226964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  test_read,
1236964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  NULL,
1246964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  NULL,
1256964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  test_ctrl,
1266964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  test_new,
1276964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  test_free,
1286964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  test_callback_ctrl,
1294687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones};
1304687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones
1314687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-JonesBIO_METHOD *BIO_s_test()
1324687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones{
1336964e0ad9224b33ce5eec47d672ee1ab21953982Jacob Appelbaum  return &test_methods;
1344687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones}
1354687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones
1364687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-JonesBIO API *BIO_new_test()
1374687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones{
138c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  return BIO_new (BIO_s_test());
1394687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones}
1404687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones
141c45952f88c568046a02bc0aea793008d8bb37755Will Drewrysize_t API BIO_test_output_left (BIO *b)
1424687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones{
143c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  return bio_ctx (b)->outsz;
1444687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones}
1454687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones
146c45952f88c568046a02bc0aea793008d8bb37755Will Drewrysize_t API BIO_test_get_output (BIO *b, unsigned char *buf, size_t bufsz)
1474687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones{
148c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  struct test_ctx *c = bio_ctx (b);
149c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  return buf_drain (&c->out, &c->outsz, buf, bufsz);
1504687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones}
1514687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones
152c45952f88c568046a02bc0aea793008d8bb37755Will Drewryvoid API BIO_test_add_input (BIO *b, const unsigned char *buf, size_t bufsz)
1534687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones{
154c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  struct test_ctx *c = bio_ctx (b);
155c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  return buf_fill (&c->in, &c->insz, buf, bufsz);
1564687c5d2e6ba965d362568f9f56239e24d76966dElly Fong-Jones}
157