/*
 * Copyright (c) 2016-2019 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef __included_uri_h__
#define __included_uri_h__

#include <vlibmemory/api.h>
#include <svm/message_queue.h>
#include <vnet/session/session_types.h>
#include <vnet/tls/tls_test.h>
#include <svm/fifo_segment.h>

typedef struct certificate_
{
  u32 *app_interests;		/* vec of application index asking for deletion cb */
  u32 cert_key_index;		/* index in cert & key pool */
  u8 *key;
  u8 *cert;
} app_cert_key_pair_t;

typedef struct session_cb_vft_
{
  /** Notify server of new segment */
  int (*add_segment_callback) (u32 app_wrk_index, u64 segment_handle);

  /** Notify server of new segment */
  int (*del_segment_callback) (u32 app_wrk_index, u64 segment_handle);

  /** Notify server of newly accepted session */
  int (*session_accept_callback) (session_t * new_session);

  /** Connection request callback */
  int (*session_connected_callback) (u32 app_wrk_index, u32 opaque,
				     session_t * s, session_error_t code);

  /** Notify app that session is closing */
  void (*session_disconnect_callback) (session_t * s);

  /** Notify app that transport is closed */
  void (*session_transport_closed_callback) (session_t * s);

  /** Notify app that session or transport are about to be removed */
  void (*session_cleanup_callback) (session_t * s, session_cleanup_ntf_t ntf);

  /** Notify app that session was reset */
  void (*session_reset_callback) (session_t * s);

  /** Notify app that session pool migration happened */
  void (*session_migrate_callback) (session_t * s, session_handle_t new_sh);

  /** Direct RX callback for built-in application */
  int (*builtin_app_rx_callback) (session_t * session);

  /** Direct TX callback for built-in application */
  int (*builtin_app_tx_callback) (session_t * session);

  /** Cert and key pair delete notification */
  int (*app_cert_key_pair_delete_callback) (app_cert_key_pair_t * ckpair);

  /** Delegate fifo-tuning-logic to application */
  int (*fifo_tuning_callback) (session_t * s, svm_fifo_t * f,
			       session_ft_action_t act, u32 bytes);

} session_cb_vft_t;

#define foreach_app_init_args			\
  _(u32, api_client_index)			\
  _(u8 *, name)					\
  _(u64 *, options)				\
  _(u8 *, namespace_id)				\
  _(session_cb_vft_t *, session_cb_vft)		\
  _(u32, app_index)				\

typedef struct _vnet_app_attach_args_t
{
#define _(_type, _name) _type _name;
  foreach_app_init_args
#undef _
  ssvm_private_t * segment;
  svm_msg_q_t *app_evt_q;
  u64 segment_handle;
} vnet_app_attach_args_t;

typedef struct _vnet_app_detach_args_t
{
  u32 app_index;
  u32 api_client_index;
} vnet_app_detach_args_t;

typedef struct _vnet_bind_args_t
{
  union
  {
    session_endpoint_cfg_t sep_ext;
    session_endpoint_t sep;
    char *uri;
  };

  u32 app_index;
  u32 wrk_map_index;

  /*
   * Results
   */
  char *segment_name;
  u32 segment_name_length;
  u64 server_event_queue_address;
  u64 handle;
} vnet_listen_args_t;

typedef struct _vnet_unlisten_args_t
{
  union
  {
    char *uri;
    u64 handle;			/**< Session handle */
  };
  u32 app_index;		/**< Owning application index */
  u32 wrk_map_index;		/**< App's local pool worker index */
} vnet_unlisten_args_t;

typedef struct _vnet_connect_args
{
  union
  {
    session_endpoint_cfg_t sep_ext;
    session_endpoint_t sep;
    char *uri;
  };
  u32 app_index;
  u32 wrk_map_index;
  u32 api_context;

  session_handle_t session_handle;
} vnet_connect_args_t;

typedef struct _vnet_disconnect_args_t
{
  session_handle_t handle;
  u32 app_index;
} vnet_disconnect_args_t;

typedef struct _vnet_application_add_tls_cert_args_t
{
  u32 app_index;
  u8 *cert;
} vnet_app_add_tls_cert_args_t;

typedef struct _vnet_application_add_tls_key_args_t
{
  u32 app_index;
  u8 *key;
} vnet_app_add_tls_key_args_t;

typedef enum crypto_engine_type_
{
  CRYPTO_ENGINE_NONE,
  CRYPTO_ENGINE_OPENSSL,
  CRYPTO_ENGINE_MBEDTLS,
  CRYPTO_ENGINE_VPP,
  CRYPTO_ENGINE_PICOTLS,
  CRYPTO_ENGINE_LAST = CRYPTO_ENGINE_PICOTLS,
} crypto_engine_type_t;

typedef struct _vnet_app_add_cert_key_pair_args_
{
  u8 *cert;
  u8 *key;
  u32 index;
} vnet_app_add_cert_key_pair_args_t;

typedef struct crypto_ctx_
{
  u32 ctx_index;		/**< index in crypto context pool */
  u32 n_subscribers;		/**< refcount of sessions using said context */
  u32 ckpair_index;		/**< certificate & key */
  u8 crypto_engine;
  void *data;			/**< protocol specific data */
} crypto_context_t;

/* Application attach options */
typedef enum
{
  APP_OPTIONS_FLAGS,
  APP_OPTIONS_EVT_QUEUE_SIZE,
  APP_OPTIONS_SEGMENT_SIZE,
  APP_OPTIONS_ADD_SEGMENT_SIZE,
  APP_OPTIONS_PRIVATE_SEGMENT_COUNT,
  APP_OPTIONS_RX_FIFO_SIZE,
  APP_OPTIONS_TX_FIFO_SIZE,
  APP_OPTIONS_PREALLOC_FIFO_PAIRS,
  APP_OPTIONS_PREALLOC_FIFO_HDRS,
  APP_OPTIONS_NAMESPACE,
  APP_OPTIONS_NAMESPACE_SECRET,
  APP_OPTIONS_PROXY_TRANSPORT,
  APP_OPTIONS_ACCEPT_COOKIE,
  APP_OPTIONS_TLS_ENGINE,
  APP_OPTIONS_MAX_FIFO_SIZE,
  APP_OPTIONS_HIGH_WATERMARK,
  APP_OPTIONS_LOW_WATERMARK,
  APP_OPTIONS_PCT_FIRST_ALLOC,
  APP_OPTIONS_N_OPTIONS
} app_attach_options_index_t;

#define foreach_app_options_flags				\
  _(ACCEPT_REDIRECT, "Use FIFO with redirects")			\
  _(ADD_SEGMENT, "Add segment and signal app if needed")	\
  _(IS_BUILTIN, "Application is builtin")			\
  _(IS_TRANSPORT_APP, "Application is a transport proto")	\
  _(IS_PROXY, "Application is proxying")			\
  _(USE_GLOBAL_SCOPE, "App can use global session scope")	\
  _(USE_LOCAL_SCOPE, "App can use local session scope")		\
  _(EVT_MQ_USE_EVENTFD, "Use eventfds for signaling")		\

typedef enum _app_options
{
#define _(sym, str) APP_OPTIONS_##sym,
  foreach_app_options_flags
#undef _
} app_options_t;

typedef enum _app_options_flags
{
#define _(sym, str) APP_OPTIONS_FLAGS_##sym = 1 << APP_OPTIONS_##sym,
  foreach_app_options_flags
#undef _
} app_options_flags_t;

#define foreach_fd_type						\
  _(VPP_MQ_SEGMENT, "Fd for vpp's event mq segment")		\
  _(MEMFD_SEGMENT, "Fd for memfd segment")			\
  _(MQ_EVENTFD, "Event fd used by message queue")		\
  _(VPP_MQ_EVENTFD, "Event fd used by vpp's message queue")	\

typedef enum session_fd_type_
{
#define _(sym, str) SESSION_FD_##sym,
  foreach_fd_type
#undef _
  SESSION_N_FD_TYPE
} session_fd_type_t;

typedef enum session_fd_flag_
{
#define _(sym, str) SESSION_FD_F_##sym = 1 << SESSION_FD_##sym,
  foreach_fd_type
#undef _
} session_fd_flag_t;

int parse_uri (char *uri, session_endpoint_cfg_t * sep);
int vnet_bind_uri (vnet_listen_args_t *);
int vnet_unbind_uri (vnet_unlisten_args_t * a);
int vnet_connect_uri (vnet_connect_args_t * a);

int vnet_application_attach (vnet_app_attach_args_t * a);
int vnet_application_detach (vnet_app_detach_args_t * a);
int vnet_listen (vnet_listen_args_t * a);
int vnet_connect (vnet_connect_args_t * a);
int vnet_unlisten (vnet_unlisten_args_t * a);
int vnet_disconnect_session (vnet_disconnect_args_t * a);

clib_error_t *vnet_app_add_tls_cert (vnet_app_add_tls_cert_args_t * a);
clib_error_t *vnet_app_add_tls_key (vnet_app_add_tls_key_args_t * a);
int vnet_app_add_cert_key_pair (vnet_app_add_cert_key_pair_args_t * a);
int vnet_app_del_cert_key_pair (u32 index);
/** Ask for app cb on pair deletion */
int vnet_app_add_cert_key_interest (u32 index, u32 app_index);

typedef struct app_session_transport_
{
  ip46_address_t rmt_ip;	/**< remote ip */
  ip46_address_t lcl_ip;	/**< local ip */
  u16 rmt_port;			/**< remote port (network order) */
  u16 lcl_port;			/**< local port (network order) */
  u8 is_ip4;			/**< set if uses ip4 networking */
} app_session_transport_t;

#define foreach_app_session_field					\
  _(svm_fifo_t, *rx_fifo)		/**< rx fifo */			\
  _(svm_fifo_t, *tx_fifo)		/**< tx fifo */			\
  _(session_type_t, session_type)	/**< session type */		\
  _(volatile u8, session_state)		/**< session state */		\
  _(u32, session_index)			/**< index in owning pool */	\
  _(app_session_transport_t, transport)	/**< transport info */		\
  _(svm_msg_q_t, *vpp_evt_q)		/**< vpp event queue  */	\
  _(u8, is_dgram)			/**< flag for dgram mode */	\

typedef struct
{
#define _(type, name) type name;
  foreach_app_session_field
#undef _
} app_session_t;

typedef struct session_listen_msg_
{
  u32 client_index;
  u32 context;			/* Not needed but keeping it for compatibility with bapi */
  u32 wrk_index;
  u32 vrf;
  u16 port;
  u8 proto;
  u8 is_ip4;
  ip46_address_t ip;
  u32 ckpair_index;
  u8 crypto_engine;
  u8 flags;
} __clib_packed session_listen_msg_t;

STATIC_ASSERT (sizeof (session_listen_msg_t) <= SESSION_CTRL_MSG_MAX_SIZE,
	       "msg too large");

typedef struct session_listen_uri_msg_
{
  u32 client_index;
  u32 context;
  u8 uri[56];
} __clib_packed session_listen_uri_msg_t;

STATIC_ASSERT (sizeof (session_listen_uri_msg_t) <= SESSION_CTRL_MSG_MAX_SIZE,
	       "msg too large");

typedef struct session_bound_msg_
{
  u32 context;
  u64 handle;
  i32 retval;
  u8 lcl_is_ip4;
  u8 lcl_ip[16];
  u16 lcl_port;
  uword rx_fifo;
  uword tx_fifo;
  uword vpp_evt_q;
  u32 segment_size;
  u8 segment_name_length;
  u8 segment_name[128];
} __clib_packed session_bound_msg_t;

typedef struct session_unlisten_msg_
{
  u32 client_index;
  u32 context;
  u32 wrk_index;
  session_handle_t handle;
} __clib_packed session_unlisten_msg_t;

typedef struct session_unlisten_reply_msg_
{
  u32 context;
  u64 handle;
  i32 retval;
} __clib_packed session_unlisten_reply_msg_t;

typedef struct session_accepted_msg_
{
  u32 context;
  u64 listener_handle;
  u64 handle;
  uword server_rx_fifo;
  uword server_tx_fifo;
  u64 segment_handle;
  uword vpp_event_queue_address;
  transport_endpoint_t rmt;
  u8 flags;
} __clib_packed session_accepted_msg_t;

typedef struct session_accepted_reply_msg_
{
  u32 context;
  i32 retval;
  u64 handle;
} __clib_packed session_accepted_reply_msg_t;

typedef struct session_connect_msg_
{
  u32 client_index;
  u32 context;
  u32 wrk_index;
  u32 vrf;
  u16 port;
  u16 lcl_port;
  u8 proto;
  u8 is_ip4;
  ip46_address_t ip;
  ip46_address_t lcl_ip;
  u8 hostname_len;
  u8 hostname[16];
  u64 parent_handle;
  u32 ckpair_index;
  u8 crypto_engine;
  u8 flags;
} __clib_packed session_connect_msg_t;

STATIC_ASSERT (sizeof (session_connect_msg_t) <= SESSION_CTRL_MSG_MAX_SIZE,
	       "msg too large");

typedef struct session_connect_uri_msg_
{
  u32 client_index;
  u32 context;
  u8 uri[56];
} __clib_packed session_connect_uri_msg_t;

STATIC_ASSERT (sizeof (session_connect_uri_msg_t) <=
	       SESSION_CTRL_MSG_MAX_SIZE, "msg too large");

typedef struct session_connected_msg_
{
  u32 context;
  i32 retval;
  u64 handle;
  uword server_rx_fifo;
  uword server_tx_fifo;
  u64 segment_handle;
  uword ct_rx_fifo;
  uword ct_tx_fifo;
  u64 ct_segment_handle;
  uword vpp_event_queue_address;
  u32 segment_size;
  u8 segment_name_length;
  u8 segment_name[64];
  transport_endpoint_t lcl;
} __clib_packed session_connected_msg_t;

typedef struct session_disconnect_msg_
{
  u32 client_index;
  u32 context;
  session_handle_t handle;
} __clib_packed session_disconnect_msg_t;

typedef struct session_disconnected_msg_
{
  u32 client_index;
  u32 context;
  u64 handle;
} __clib_packed session_disconnected_msg_t;

typedef struct session_disconnected_reply_msg_
{
  u32 context;
  i32 retval;
  u64 handle;
} __clib_packed session_disconnected_reply_msg_t;

typedef struct session_reset_msg_
{
  u32 client_index;
  u32 context;
  u64 handle;
} __clib_packed session_reset_msg_t;

typedef struct session_reset_reply_msg_
{
  u32 context;
  i32 retval;
  u64 handle;
} __clib_packed session_reset_reply_msg_t;

typedef struct session_req_worker_update_msg_
{
  u64 session_handle;
} __clib_packed session_req_worker_update_msg_t;

/* NOTE: using u16 for wrk indices because message needs to fit in 18B */
typedef struct session_worker_update_msg_
{
  u32 client_index;
  u16 wrk_index;
  u16 req_wrk_index;
  u64 handle;
} __clib_packed session_worker_update_msg_t;

typedef struct session_worker_update_reply_msg_
{
  u64 handle;
  uword rx_fifo;
  uword tx_fifo;
  u64 segment_handle;
} __clib_packed session_worker_update_reply_msg_t;

typedef struct session_app_detach_msg_
{
  u32 client_index;
  u32 context;
} session_app_detach_msg_t;

typedef struct app_map_another_segment_msg_
{
  u32 client_index;
  u32 context;
  u8 fd_flags;
  u32 segment_size;
  u8 segment_name[128];
  u64 segment_handle;
} session_app_add_segment_msg_t;

typedef struct app_unmap_segment_msg_
{
  u32 client_index;
  u32 context;
  u64 segment_handle;
} session_app_del_segment_msg_t;

typedef struct session_migrate_msg_
{
  uword vpp_evt_q;
  session_handle_t handle;
  session_handle_t new_handle;
  u32 vpp_thread_index;
} __clib_packed session_migrated_msg_t;

typedef struct session_cleanup_msg_
{
  session_handle_t handle;
  u8 type;
} __clib_packed session_cleanup_msg_t;

typedef struct session_app_wrk_rpc_msg_
{
  u32 client_index;	/**< app client index */
  u32 wrk_index;	/**< dst worker index */
  u8 data[64];		/**< rpc data */
} __clib_packed session_app_wrk_rpc_msg_t;

typedef struct app_session_event_
{
  svm_msg_q_msg_t msg;
  session_event_t *evt;
} __clib_packed app_session_evt_t;

static inline void
app_alloc_ctrl_evt_to_vpp (svm_msg_q_t * mq, app_session_evt_t * app_evt,
			   u8 evt_type)
{
  svm_msg_q_lock_and_alloc_msg_w_ring (mq,
				       SESSION_MQ_CTRL_EVT_RING,
				       SVM_Q_WAIT, &app_evt->msg);
  app_evt->evt = svm_msg_q_msg_data (mq, &app_evt->msg);
  clib_memset (app_evt->evt, 0, sizeof (*app_evt->evt));
  app_evt->evt->event_type = evt_type;
}

static inline void
app_send_ctrl_evt_to_vpp (svm_msg_q_t * mq, app_session_evt_t * app_evt)
{
  svm_msg_q_add_and_unlock (mq, &app_evt->msg);
}

/**
 * Send fifo io event to vpp worker thread
 *
 * Because there may be multiple writers to one of vpp's queues, this
 * protects message allocation and enqueueing.
 *
 * @param mq		vpp message queue
 * @param f		fifo for which the event is sent
 * @param evt_type	type of event
 * @param noblock	flag to indicate is request is blocking or not
 * @return		0 if success, negative integer otherwise
 */
static inline int
app_send_io_evt_to_vpp (svm_msg_q_t * mq, u32 session_index, u8 evt_type,
			u8 noblock)
{
  session_event_t *evt;
  svm_msg_q_msg_t msg;

  if (noblock)
    {
      if (svm_msg_q_try_lock (mq))
	return -1;
      if (PREDICT_FALSE (svm_msg_q_ring_is_full (mq, SESSION_MQ_IO_EVT_RING)))
	{
	  svm_msg_q_unlock (mq);
	  return -2;
	}
      msg = svm_msg_q_alloc_msg_w_ring (mq, SESSION_MQ_IO_EVT_RING);
      evt = (session_event_t *) svm_msg_q_msg_data (mq, &msg);
      evt->session_index = session_index;
      evt->event_type = evt_type;
      svm_msg_q_add_and_unlock (mq, &msg);
      return 0;
    }
  else
    {
      svm_msg_q_lock (mq);
      while (svm_msg_q_ring_is_full (mq, SESSION_MQ_IO_EVT_RING)
	     || svm_msg_q_is_full (mq))
	svm_msg_q_wait (mq);
      msg = svm_msg_q_alloc_msg_w_ring (mq, SESSION_MQ_IO_EVT_RING);
      evt = (session_event_t *) svm_msg_q_msg_data (mq, &msg);
      evt->session_index = session_index;
      evt->event_type = evt_type;
      svm_msg_q_add_and_unlock (mq, &msg);
      return 0;
    }
}

always_inline int
app_send_dgram_raw (svm_fifo_t * f, app_session_transport_t * at,
		    svm_msg_q_t * vpp_evt_q, u8 * data, u32 len, u8 evt_type,
		    u8 do_evt, u8 noblock)
{
  u32 max_enqueue, actual_write;
  session_dgram_hdr_t hdr;
  int rv;

  max_enqueue = svm_fifo_max_enqueue_prod (f);
  if (max_enqueue < (sizeof (session_dgram_hdr_t) + len))
    return 0;

  max_enqueue -= sizeof (session_dgram_hdr_t);
  actual_write = clib_min (len, max_enqueue);
  hdr.data_length = actual_write;
  hdr.data_offset = 0;
  clib_memcpy_fast (&hdr.rmt_ip, &at->rmt_ip, sizeof (ip46_address_t));
  hdr.is_ip4 = at->is_ip4;
  hdr.rmt_port = at->rmt_port;
  clib_memcpy_fast (&hdr.lcl_ip, &at->lcl_ip, sizeof (ip46_address_t));
  hdr.lcl_port = at->lcl_port;
  rv = svm_fifo_enqueue (f, sizeof (hdr), (u8 *) & hdr);
  ASSERT (rv == sizeof (hdr));

  rv = svm_fifo_enqueue (f, actual_write, data);
  if (do_evt)
    {
      if (rv > 0 && svm_fifo_set_event (f))
	app_send_io_evt_to_vpp (vpp_evt_q, f->master_session_index, evt_type,
				noblock);
    }
  ASSERT (rv);
  return rv;
}

always_inline int
app_send_dgram (app_session_t * s, u8 * data, u32 len, u8 noblock)
{
  return app_send_dgram_raw (s->tx_fifo, &s->transport, s->vpp_evt_q, data,
			     len, SESSION_IO_EVT_TX, 1 /* do_evt */ ,
			     noblock);
}

always_inline int
app_send_stream_raw (svm_fifo_t * f, svm_msg_q_t * vpp_evt_q, u8 * data,
		     u32 len, u8 evt_type, u8 do_evt, u8 noblock)
{
  int rv;

  rv = svm_fifo_enqueue (f, len, data);
  if (do_evt)
    {
      if (rv > 0 && svm_fifo_set_event (f))
	app_send_io_evt_to_vpp (vpp_evt_q, f->master_session_index, evt_type,
				noblock);
    }
  return rv;
}

always_inline int
app_send_stream (app_session_t * s, u8 * data, u32 len, u8 noblock)
{
  return app_send_stream_raw (s->tx_fifo, s->vpp_evt_q, data, len,
			      SESSION_IO_EVT_TX, 1 /* do_evt */ , noblock);
}

always_inline int
app_send (app_session_t * s, u8 * data, u32 len, u8 noblock)
{
  if (s->is_dgram)
    return app_send_dgram (s, data, len, noblock);
  return app_send_stream (s, data, len, noblock);
}

always_inline int
app_recv_dgram_raw (svm_fifo_t * f, u8 * buf, u32 len,
		    app_session_transport_t * at, u8 clear_evt, u8 peek)
{
  session_dgram_pre_hdr_t ph;
  u32 max_deq;
  int rv;

  max_deq = svm_fifo_max_dequeue_cons (f);
  if (max_deq <= sizeof (session_dgram_hdr_t))
    {
      if (clear_evt)
	svm_fifo_unset_event (f);
      return 0;
    }

  if (clear_evt)
    svm_fifo_unset_event (f);

  svm_fifo_peek (f, 0, sizeof (ph), (u8 *) & ph);
  ASSERT (ph.data_length >= ph.data_offset);

  /* Check if we have the full dgram */
  if (max_deq < (ph.data_length + SESSION_CONN_HDR_LEN)
      && len >= ph.data_length)
    return 0;

  svm_fifo_peek (f, sizeof (ph), sizeof (*at), (u8 *) at);
  len = clib_min (len, ph.data_length - ph.data_offset);
  rv = svm_fifo_peek (f, ph.data_offset + SESSION_CONN_HDR_LEN, len, buf);
  if (peek)
    return rv;

  /* Discards data that did not fit in buffer */
  svm_fifo_dequeue_drop (f, ph.data_length + SESSION_CONN_HDR_LEN);

  return rv;
}

always_inline int
app_recv_dgram (app_session_t * s, u8 * buf, u32 len)
{
  return app_recv_dgram_raw (s->rx_fifo, buf, len, &s->transport, 1, 0);
}

always_inline int
app_recv_stream_raw (svm_fifo_t * f, u8 * buf, u32 len, u8 clear_evt, u8 peek)
{
  if (clear_evt)
    svm_fifo_unset_event (f);

  if (peek)
    return svm_fifo_peek (f, 0, len, buf);

  return svm_fifo_dequeue (f, len, buf);
}

always_inline int
app_recv_stream (app_session_t * s, u8 * buf, u32 len)
{
  return app_recv_stream_raw (s->rx_fifo, buf, len, 1, 0);
}

always_inline int
app_recv (app_session_t * s, u8 * data, u32 len)
{
  if (s->is_dgram)
    return app_recv_dgram (s, data, len);
  return app_recv_stream (s, data, len);
}

/* *INDENT-OFF* */
static char *session_error_str[] = {
#define _(sym, str) str,
    foreach_session_error
#undef _
};
/* *INDENT-ON* */

static inline u8 *
format_session_error (u8 * s, va_list * args)
{
  session_error_t error = va_arg (*args, session_error_t);
  if (-error >= 0 && -error < SESSION_N_ERRORS)
    s = format (s, "%s", session_error_str[-error]);
  else
    s = format (s, "invalid session err %u", -error);
  return s;
}
#endif /* __included_uri_h__ */

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
