/*
 * nasd_pipe.h
 *
 * NASD byte pipe functions
 *
 * Authors: Jim Zelenka, Nat Lanza
 */
/*
 * Copyright (c) of Carnegie Mellon University, 1999.
 *
 * Permission to reproduce, use, and prepare derivative works of
 * this software for internal use is granted provided the copyright
 * and "No Warranty" statements are included with all reproductions
 * and derivative works. This software may also be redistributed
 * without charge provided that the copyright and "No Warranty"
 * statements are included in all redistributions.
 *
 * NO WARRANTY. THIS SOFTWARE IS FURNISHED ON AN "AS IS" BASIS.
 * CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER
 * EXPRESSED OR IMPLIED AS TO THE MATTER INCLUDING, BUT NOT LIMITED
 * TO: WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY
 * OF RESULTS OR RESULTS OBTAINED FROM USE OF THIS SOFTWARE. CARNEGIE
 * MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT
 * TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
 */


#ifndef _NASD_PIPE_H_
#define _NASD_PIPE_H_

#include <nasd/nasd_options.h>
#include <nasd/nasd_threadstuff.h>
#include <nasd/nasd_shutdown.h>
#include <nasd/nasd_types.h>
#include <nasd/nasd_security.h>

#if NASD_RPC_PACKAGE == NASD_RPC_PACKAGE_DCE
#include <nasd/nasd_pipe_dce.h>
#endif /* NASD_RPC_PACKAGE == NASD_RPC_PACKAGE_DCE */

/* you probably want this to be the same as NASD_OD_BASIC_BLOCKSIZE. */
#define NASD_EBUF_SIZE                  8192

typedef struct nasd_co_pipe_state_s     nasd_co_pipe_state_t;
typedef struct nasd_cl_fo_list_state_s  nasd_cl_fo_list_state_t;
typedef struct nasd_cl_fo_state_s       nasd_cl_fo_state_t;
typedef struct nasd_cl_dg_s             nasd_cl_dg_t;
typedef struct nasd_procpipe_s          nasd_procpipe_t;
typedef struct nasd_net_pipe_state_s    nasd_net_pipe_state_t;
typedef struct nasd_ebuf_s              nasd_ebuf_t;

struct nasd_procpipe_s {
  void            *state;
  nasd_status_t  (*push)(void *state_arg,
                         void *buf,
                         nasd_len_t len,
                         nasd_byte_t *in_digest,
                         nasd_byte_t *out_digest,
                         int *digest_valid);
  nasd_status_t  (*pull)(void *state_arg,
                         void *buf,
                         nasd_len_t len,
                         nasd_len_t *out_len,
                         nasd_byte_t *out_digest,
                         int *digest_valid,
                         void (*commit)(void *, nasd_offset_t, nasd_len_t),
                         void *commit_rock);
};


struct nasd_net_pipe_state_s {
  void *rpc_state;
  nasd_status_t (*push)(void *, void *, nasd_len_t);
  nasd_status_t (*pull)(void *, void *, nasd_len_t, nasd_len_t *);
  nasd_security_context_t *context;
};

struct nasd_co_pipe_state_s {
  nasd_byte_t  *orig_buf;
  nasd_byte_t  *cur_buf;
  int           orig_buf_len;
  int           buf_len_remain;
};

struct nasd_cl_fo_state_s {
  int            dce_bug;
  char          *buf;
  unsigned int   len;           /* total amount of data being sent */
  unsigned int   alloc_off;     /* offset into datastream has been alloced */
  unsigned int   push_off;      /* offset in the datastream has been push/pulled */
  nasd_security_context_t  context;
  
  /* these are all to keep track of our place in the data stream when
     we are pulling, and thus doing incremental digests */
  unsigned int   alloc_adj;
  int            alloc_digest;  /* are we allocing a digest? */
  int            pull_digest;   /* are we pulling a digest? */
  int            digest_alloc_off; /* digest offset alloced */
  int            digest_pull_off; /* digest offset push/pulled */
  int            digest_len;    /* length of digest */
  char          *digest_buf;    /* current digest buf */
  nasd_offset_t  next_alloc_digest_off;
  nasd_offset_t  next_pull_digest_off;
};

struct nasd_cl_fo_list_state_s {
  int               dce_bug;

  nasd_len_t       *out_lenp;
  nasd_len_t        targetlen;
  int               badstate;
  nasd_mem_list_t  *alloc_cur;
  int               alloc_elem;
  nasd_byte_t      *alloc_buf;
  unsigned int      alloc_off;
  unsigned int      alloc_len;
  nasd_mem_list_t  *push_cur;
  int               push_elem;
  nasd_byte_t      *push_buf;
  unsigned int      push_off;
  unsigned int      push_len;
  nasd_status_t     status;
  nasd_security_context_t  context;
  /* shadow buffers to handle encryption without corrupting client's
     buffer -- only for pull */
  nasd_mem_list_t  *shadow;
  /* keep track of overall position in object */
  nasd_offset_t     alloc_adj;
  nasd_offset_t     push_adj;
  /* handle incremental digests, also only for pull */
  nasd_cl_dg_t     *digest_alloc_cur;
  nasd_byte_t      *digest_alloc_buf;
  unsigned int      digest_alloc_off;
  nasd_cl_dg_t     *digest_pull_cur;
  nasd_byte_t      *digest_pull_buf;
  unsigned int      digest_pull_off;
  int               alloc_digest;
  int               pull_digest;
  nasd_offset_t     next_alloc_digest_off;
  nasd_offset_t     next_pull_digest_off;
};

/* digest buffer */
struct nasd_cl_dg_s {
  nasd_digest_t     digest;
  nasd_cl_dg_t     *next;
};

/* encryption buffer */
struct nasd_ebuf_s {
  nasd_byte_t       buf[NASD_EBUF_SIZE];
  nasd_ebuf_t      *next;
};

extern nasd_freelist_t *nasd_cl_fo_state_freelist;
extern nasd_freelist_t *nasd_cl_fo_list_state_freelist;

void nasd_cl_shutdown_fo_state_fl(void *ignored);
void nasd_cl_shutdown_fo_state_list_fl(void *ignored);
void nasd_pipe_cb_read_alloc(nasd_cl_fo_state_t *s, nasd_uint32 bsize,
  nasd_byte_t **buf, nasd_uint32 *bcount);
void nasd_pipe_cb_write_alloc(nasd_cl_fo_state_t *s, nasd_uint32 bsize,
  nasd_byte_t **buf, nasd_uint32 *bcount);
void nasd_pipe_cb_read_push(nasd_cl_fo_state_t *s,
  nasd_byte_t *buf, nasd_uint32 count);
void nasd_pipe_cb_write_pull(nasd_cl_fo_state_t *s,
  nasd_byte_t *buf, nasd_uint32 in_count, nasd_uint32 *out_count);
void nasd_pipe_cb_read_alloc_list(nasd_cl_fo_list_state_t *s, nasd_uint32 bsize,
  nasd_byte_t **buf, nasd_uint32 *bcount);
void nasd_pipe_cb_write_alloc_list(nasd_cl_fo_list_state_t *s, nasd_uint32 bsize,
  nasd_byte_t **buf, nasd_uint32 *bcount);
void nasd_pipe_cb_read_push_list(nasd_cl_fo_list_state_t *s,
  nasd_byte_t *buf, nasd_uint32 count);
void nasd_pipe_cb_write_pull_list(nasd_cl_fo_list_state_t *s,
  nasd_byte_t *buf, nasd_uint32 in_count, nasd_uint32 *out_count);
nasd_status_t nasd_cl_pipe_init(nasd_shutdown_list_t *sl);
nasd_status_t nasd_co_pull(void *state_arg, void *buf,
  nasd_len_t in_len, nasd_len_t *out_lenp, nasd_byte_t *ign1,
  int *ign2, void (*ign3)(), void *ign4);
nasd_status_t nasd_co_push(void *state_arg, void *buf,
  nasd_len_t in_len, nasd_byte_t *ign1, nasd_byte_t *ign2, int *ign3);
nasd_status_t nasd_pipe_init(nasd_shutdown_list_t *sl);
nasd_status_t nasd_pipe_push(void *state_arg, void *buf, nasd_len_t len,
                             nasd_byte_t *in_digest, nasd_byte_t *out_digest,
                             int *digest_valid);
nasd_status_t nasd_pipe_pull(void *state_arg, void *buf,
                             nasd_len_t len, nasd_len_t *out_len,
                             nasd_byte_t *out_digest, int *digest_valid,
                             void (*commit)(void *, nasd_offset_t, nasd_len_t),
                             void *commit_rock);

#endif /* !_NASD_PIPE_H_ */

/* Local Variables:  */
/* indent-tabs-mode: nil */
/* tab-width: 2 */
/* End: */
