/***************************************************************************
 *
 * Copyright (c) 2000, 2001 BalaBit IT Ltd, Budapest, Hungary
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * $Id: proxy.h,v 1.28.2.3.2.4 2001/09/19 19:22:17 bazsi Exp $
 *
 ***************************************************************************/

#ifndef ZORP_PROXY_H_INCLUDED
#define ZORP_PROXY_H_INCLUDED

#include <zorp/ctrack.h>
#include <zorp/stream.h>
#include <zorp/zpython.h>

/* a two-way connection between streams */

/* endpoint indexes */
#define EP_CLIENT      0
#define EP_SERVER      1
#define EP_MAX         2

/* flags */

/* proxy states */
#define PS_CONFIG         0
#define PS_STARTING_UP    1
#define PS_WORKING        2
#define PS_SHUTTING_DOWN  3

/* proxy flags */

#define PF_QUIT           0x00000100

#define PF_STATE          0x000000FF
#define PF_FLAGS          0x0000FF00
#define PF_USER           0xFFFF0000

/* first available flag for use */
#define PF_USER_FLAG      0x00010000

#define Z_VAR_GET		0x00000001	/* variable can be read */
#define Z_VAR_SET		0x00000002	/* variable can be written */
#define Z_VAR_GET_CONFIG	0x00000004	
#define Z_VAR_SET_CONFIG	0x00000008	
#define Z_VAR_GET_VERBOSE	0x00000010
#define Z_VAR_SET_VERBOSE	0x00000020

#define Z_VAR_TYPE(t) ((t) & 0x0000ff00)

#define Z_VAR_TYPE_INT		0x00000100	/* variable is an int */
#define Z_VAR_TYPE_STRING	0x00000200	/* variable is a string */
#define Z_VAR_TYPE_SOCKADDR	0x00000300	/* variable is a sockaddr */
#define Z_VAR_TYPE_OBJECT       0x00000400	/* variable is a policy object */
#define Z_VAR_TYPE_HASH		0x00000500	/* variable is a hash */
#define Z_VAR_TYPE_METHOD	0x00000600      /* variable is a method */
#define Z_VAR_TYPE_CUSTOM	0x00000700	/* variable is something, requests are 
                                                   processed via a function call */
#define Z_VAR_TYPE_DIMHASH	0x00000800      /* variable is a multidimensional hash */
#define Z_VAR_TYPE_ALIAS	0x00001000	/* variable is an alias of another variable */

#define MAX_SESSION_ID		64

typedef struct _ZProxy
{
  gchar session_id[MAX_SESSION_ID];
  int flags;
  ZPolicyObj *handler;
  ZPolicyThread *thread;
  GHashTable *vars;
  
  ZPolicyObj *(*getattr)(struct _ZProxy *self, char *name);
  gint (*setattr)(struct _ZProxy *self, char *name, ZPolicyObj *value);
  void (*free)(struct _ZProxy *);
  void (*connect_stop)(struct _ZProxy *, struct _ZCProxy *, gpointer sess);
  void (*connect_init)(struct _ZProxy *self, struct _ZCProxy *clientct, struct _ZCProxy *serverct);
  gpointer (*connect_setup)(struct _ZProxy *self, gchar *clientsession);
  void (*packet_read)(struct _ZProxy *self, struct _ZPacket *packet, guint way, gpointer sess);
  ZStream *endpoints[EP_MAX];
} ZProxy;

typedef struct _ZStackedProxy
{
  ZStream *downstreams[EP_MAX];
} ZStackedProxy;

#define ZPROXY_GETATTR(zp, n) (*(zp)->getattr)(zp, n)
#define ZPROXY_SETATTR(zp, n, v) (*(zp)->setattr)(zp, n, v)

/* state management macros */
#define ZPROXY_GET_STATE(p) (((ZProxy *) p)->flags & 0xff)
#define ZPROXY_SET_STATE(p, s) (((ZProxy *) p)->flags = (((ZProxy *) p)->flags & ~PF_STATE) | s)

#define ZPROXY_GET_FLAG(p, f) (((ZProxy *) p)->flags & f)
#define ZPROXY_SET_FLAG(p, f) (((ZProxy *) p)->flags = (((ZProxy *) p)->flags & ~PF_FLAGS) | f)

typedef ZProxy *(*ZSProxyCreateFunc)(char *session_id, ZStream *client, ZPolicyObj *handler);

typedef ZProxy *(*ZDProxyCreateFunc)(char *session_id, ZPolicyObj *handler);

typedef ZProxy *(*ZPyProxyCreateFunc)(char *session_id, ZPolicyObj *client, ZPolicyObj *handler);

typedef gint (*ZProxySetVarFunc)(ZProxy *self, gchar *name, gpointer value, ZPolicyObj *new);
typedef ZPolicyObj *(*ZProxyGetVarFunc)(ZProxy *self, gchar *name, gpointer value);

typedef ZPolicyObj *(*ZProxyMethodFunc)(ZProxy *self, ZPolicyObj *args);

void 
z_proxy_init(ZProxy *zp, 
             gchar *session_id,
	     ZStream *client, 
	     ZPolicyObj *handler);

void z_proxy_destroy(ZProxy *zp);
void z_proxy_free(ZProxy *zp);

void z_proxy_var_new(ZProxy *self, gchar *name, guint flags, ...);
void z_proxy_quit(ZProxy *self);

gboolean z_proxy_config_event(ZProxy *);
gboolean z_proxy_startup_event(ZProxy *);
void z_proxy_shutdown_event(ZProxy *);
gint z_proxy_connect_server_event(ZProxy *self, char *host, gint port);
void z_proxy_destroy_event(ZProxy *self); 
gint z_proxy_user_authenticated(ZProxy *self, gchar *entity);
ZStackedProxy *z_proxy_stack_proxy(ZProxy *self, ZPolicyObj *proxy_class);

ZStackedProxy *z_stacked_proxy_new(gint client_fd, gint server_fd, ZProxy *proxy);
void z_stacked_proxy_destroy(ZStackedProxy *self);


#endif
