/*
 *------------------------------------------------------------------
 * socksvr_vlib.c
 *
 * Copyright (c) 2009 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.
 *------------------------------------------------------------------
 */

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <vppinfra/byte_order.h>

#include <fcntl.h>
#include <sys/stat.h>

#include <vlibsocket/api.h>
#include <vlibmemory/api.h>

#include <vlibsocket/vl_socket_msg_enum.h>	/* enumerate all vlib messages */

#define vl_typedefs		/* define message structures */
#include <vlibsocket/vl_socket_api_h.h>
#undef vl_typedefs

/* instantiate all the print functions we know about */
#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
#define vl_printfun
#include <vlibsocket/vl_socket_api_h.h>
#undef vl_printfun

/* instantiate all the endian swap functions we know about */
#define vl_endianfun
#include <vlibsocket/vl_socket_api_h.h>
#undef vl_endianfun

socket_main_t socket_main;

void
dump_socket_clients (vlib_main_t * vm, api_main_t * am)
{
  vl_api_registration_t *reg;
  socket_main_t *sm = &socket_main;
  unix_main_t *um = &unix_main;
  unix_file_t *f;

  /*
   * Must have at least one active client, not counting the
   * REGISTRATION_TYPE_SOCKET_LISTEN bind/accept socket
   */
  if (pool_elts (sm->registration_pool) < 2)
    return;

  vlib_cli_output (vm, "TCP socket clients");
  vlib_cli_output (vm, "%16s %8s", "Name", "Fildesc");
    /* *INDENT-OFF* */
    pool_foreach (reg, sm->registration_pool,
    ({
        if (reg->registration_type == REGISTRATION_TYPE_SOCKET_SERVER) {
            f = pool_elt_at_index (um->file_pool, reg->unix_file_index);
            vlib_cli_output (vm, "%16s %8d",
                             reg->name, f->file_descriptor);
        }
    }));
/* *INDENT-ON* */
}

void
vl_socket_api_send (vl_api_registration_t * rp, u8 * elem)
{
  u32 nbytes = 4;		/* for the length... */
  u16 msg_id = ntohs (*(u16 *) elem);
  u32 msg_length;
  u32 tmp;
  api_main_t *am = &api_main;

  ASSERT (rp->registration_type > REGISTRATION_TYPE_SHMEM);

  if (msg_id >= vec_len (am->api_trace_cfg))
    {
      clib_warning ("id out of range: %d", msg_id);
      vl_msg_api_free ((void *) elem);
      return;
    }

  msg_length = am->api_trace_cfg[msg_id].size;
  nbytes += msg_length;
  tmp = clib_host_to_net_u32 (nbytes);

  vl_socket_add_pending_output (rp->unix_file_index
				+ unix_main.file_pool,
				rp->vl_api_registration_pool_index
				+ socket_main.registration_pool,
				(u8 *) & tmp, sizeof (tmp));
  vl_socket_add_pending_output (rp->unix_file_index
				+ unix_main.file_pool,
				rp->vl_api_registration_pool_index
				+ socket_main.registration_pool,
				elem, msg_length);
  vl_msg_api_free ((void *) elem);
}

void
vl_socket_api_send_with_data (vl_api_registration_t * rp,
			      u8 * elem, u8 * data_vector)
{
  u32 nbytes = 4;		/* for the length... */
  u16 msg_id = ntohs (*(u16 *) elem);
  u32 msg_length;
  u32 tmp;
  api_main_t *am = &api_main;

  ASSERT (rp->registration_type > REGISTRATION_TYPE_SHMEM);

  if (msg_id >= vec_len (am->api_trace_cfg))
    {
      clib_warning ("id out of range: %d", msg_id);
      vec_free (data_vector);
      vl_msg_api_free ((void *) elem);
      return;
    }

  msg_length = am->api_trace_cfg[msg_id].size;
  nbytes += msg_length;
  nbytes += vec_len (data_vector);

  /* Length in network byte order */
  tmp = clib_host_to_net_u32 (nbytes);

  vl_socket_add_pending_output (rp->unix_file_index
				+ unix_main.file_pool,
				rp->vl_api_registration_pool_index
				+ socket_main.registration_pool,
				(u8 *) & tmp, sizeof (tmp));
  vl_socket_add_pending_output (rp->unix_file_index
				+ unix_main.file_pool,
				rp->vl_api_registration_pool_index
				+ socket_main.registration_pool,
				elem, msg_length);
  vl_socket_add_pending_output (rp->unix_file_index
				+ unix_main.file_pool,
				rp->vl_api_registration_pool_index
				+ socket_main.registration_pool,
				data_vector, vec_len (data_vector));
  vl_msg_api_free ((void *) elem);
}

static inline void
vl_socket_api_send_with_length_internal (vl_api_registration_t * rp,
					 u8 * elem, u32 msg_length, int free)
{
  u32 nbytes = 4;		/* for the length... */
  u16 msg_id = ntohs (*(u16 *) elem);
  u32 tmp;
  api_main_t *am = &api_main;

  ASSERT (rp->registration_type > REGISTRATION_TYPE_SHMEM);

  if (msg_id >= vec_len (am->api_trace_cfg))
    {
      clib_warning ("id out of range: %d", msg_id);
      if (free)
	vl_msg_api_free ((void *) elem);
      return;
    }

  nbytes += msg_length;

  /* Length in network byte order */
  tmp = clib_host_to_net_u32 (nbytes);

  vl_socket_add_pending_output (rp->unix_file_index
				+ unix_main.file_pool,
				rp->vl_api_registration_pool_index
				+ socket_main.registration_pool,
				(u8 *) & tmp, sizeof (tmp));
  vl_socket_add_pending_output (rp->unix_file_index
				+ unix_main.file_pool,
				rp->vl_api_registration_pool_index
				+ socket_main.registration_pool,
				elem, msg_length);
  if (free)
    vl_msg_api_free ((void *) elem);
}

void
vl_socket_api_send_with_length (vl_api_registration_t * rp,
				u8 * elem, u32 msg_length)
{
  vl_socket_api_send_with_length_internal (rp, elem, msg_length,
					   1 /* free */ );
}

void
vl_socket_api_send_with_length_no_free (vl_api_registration_t * rp,
					u8 * elem, u32 msg_length)
{
  vl_socket_api_send_with_length_internal (rp, elem, msg_length,
					   0 /* free */ );
}

void
vl_free_socket_registration_index (u32 pool_index)
{
  vl_api_registration_t *rp;
  if (pool_is_free_index (socket_main.registration_pool, pool_index))
    {
      clib_warning ("main pool index %d already free", pool_index);
      return;
    }
  rp = pool_elt_at_index (socket_main.registration_pool, pool_index);

  ASSERT (rp->registration_type != REGISTRATION_TYPE_FREE);
  vec_free (rp->name);
  vec_free (rp->unprocessed_input);
  vec_free (rp->output_vector);
  rp->registration_type = REGISTRATION_TYPE_FREE;
  pool_put (socket_main.registration_pool, rp);
}

static inline void
socket_process_msg (unix_file_t * uf, vl_api_registration_t * rp,
		    i8 * input_v)
{
  u8 *the_msg = (u8 *) (input_v + sizeof (u32));
  socket_main.current_uf = uf;
  socket_main.current_rp = rp;
  vl_msg_api_socket_handler (the_msg);
  socket_main.current_uf = 0;
  socket_main.current_rp = 0;
}

clib_error_t *
vl_socket_read_ready (unix_file_t * uf)
{
  unix_main_t *um = &unix_main;
  vl_api_registration_t *rp;
  int n;
  i8 *msg_buffer = 0;
  u32 msg_len;
  u32 save_input_buffer_length = vec_len (socket_main.input_buffer);

  rp = pool_elt_at_index (socket_main.registration_pool, uf->private_data);

  n = read (uf->file_descriptor, socket_main.input_buffer,
	    vec_len (socket_main.input_buffer));

  if (n <= 0 && errno != EAGAIN)
    {
      unix_file_del (um, uf);

      if (!pool_is_free (socket_main.registration_pool, rp))
	{
	  u32 index = rp - socket_main.registration_pool;
	  vl_free_socket_registration_index (index);
	}
      else
	{
	  clib_warning ("client index %d already free?",
			rp->vl_api_registration_pool_index);
	}
      return 0;
    }

  _vec_len (socket_main.input_buffer) = n;

  /*
   * Look for bugs here. This code is tricky because
   * data read from a stream socket does honor message
   * boundaries. In the case of a long message (>4K bytes)
   * we have to do (at least) 2 reads, etc.
   */
  do
    {
      if (vec_len (rp->unprocessed_input))
	{
	  vec_append (rp->unprocessed_input, socket_main.input_buffer);
	  msg_buffer = rp->unprocessed_input;
	  msg_len = rp->unprocessed_msg_length;
	}
      else
	{
	  msg_buffer = socket_main.input_buffer;
	  msg_len = 0;
	}

      if (msg_len == 0)
	{
	  /* Length may be split across two reads */
	  if (vec_len (msg_buffer) < sizeof (u32))
	    goto save_and_split;

	  /* total length, including msg_len itself, in network byte order */
	  msg_len = clib_net_to_host_u32 (*((u32 *) msg_buffer));
	}

      /* Happens if the client sent msg_len == 0 */
      if (msg_len == 0)
	{
	  clib_warning ("msg_len == 0");
	  goto turf_it;
	}

      /* We don't have the entire message yet. */
      if (msg_len > vec_len (msg_buffer))
	{
	save_and_split:
	  /*
	   * if we were using the shared input buffer,
	   * save the fragment.
	   */
	  if (msg_buffer == socket_main.input_buffer)
	    {
	      ASSERT (vec_len (rp->unprocessed_input) == 0);
	      vec_validate (rp->unprocessed_input, vec_len (msg_buffer) - 1);
	      clib_memcpy (rp->unprocessed_input, msg_buffer,
			   vec_len (msg_buffer));
	      _vec_len (rp->unprocessed_input) = vec_len (msg_buffer);
	    }
	  _vec_len (socket_main.input_buffer) = save_input_buffer_length;
	  rp->unprocessed_msg_length = msg_len;
	  return 0;
	}

      socket_process_msg (uf, rp, msg_buffer);
      if (n > msg_len)
	vec_delete (msg_buffer, msg_len, 0);
      else
	_vec_len (msg_buffer) = 0;
      n -= msg_len;
      msg_len = 0;
      rp->unprocessed_msg_length = 0;
    }
  while (n > 0);

turf_it:
  _vec_len (socket_main.input_buffer) = save_input_buffer_length;

  return 0;
}

void
vl_socket_add_pending_output (unix_file_t * uf,
			      vl_api_registration_t * rp,
			      u8 * buffer, uword buffer_bytes)
{
  unix_main_t *um = &unix_main;

  vec_add (rp->output_vector, buffer, buffer_bytes);
  if (vec_len (rp->output_vector) > 0)
    {
      int skip_update = 0 != (uf->flags & UNIX_FILE_DATA_AVAILABLE_TO_WRITE);
      uf->flags |= UNIX_FILE_DATA_AVAILABLE_TO_WRITE;
      if (!skip_update)
	um->file_update (uf, UNIX_FILE_UPDATE_MODIFY);
    }
}

static void
socket_del_pending_output (unix_file_t * uf,
			   vl_api_registration_t * rp, uword n_bytes)
{
  unix_main_t *um = &unix_main;

  vec_delete (rp->output_vector, n_bytes, 0);
  if (vec_len (rp->output_vector) <= 0)
    {
      int skip_update = 0 == (uf->flags & UNIX_FILE_DATA_AVAILABLE_TO_WRITE);
      uf->flags &= ~UNIX_FILE_DATA_AVAILABLE_TO_WRITE;
      if (!skip_update)
	um->file_update (uf, UNIX_FILE_UPDATE_MODIFY);
    }
}

clib_error_t *
vl_socket_write_ready (unix_file_t * uf)
{
  unix_main_t *um = &unix_main;
  vl_api_registration_t *rp;
  int n;

  rp = pool_elt_at_index (socket_main.registration_pool, uf->private_data);

  /* Flush output vector. */
  n = write (uf->file_descriptor,
	     rp->output_vector, vec_len (rp->output_vector));

  if (n < 0)
    {
#if DEBUG > 2
      clib_warning ("write error, close the file...\n");
#endif
      unix_file_del (um, uf);

      vl_free_socket_registration_index (rp - socket_main.registration_pool);
      return 0;
    }

  else if (n > 0)
    socket_del_pending_output (uf, rp, n);

  return 0;
}

clib_error_t *
vl_socket_error_ready (unix_file_t * uf)
{
  vl_api_registration_t *rp;
  unix_main_t *um = &unix_main;

  rp = pool_elt_at_index (socket_main.registration_pool, uf->private_data);
  unix_file_del (um, uf);
  vl_free_socket_registration_index (rp - socket_main.registration_pool);

  return 0;
}

void
socksvr_file_add (unix_main_t * um, int fd)
{
  vl_api_registration_t *rp;
  unix_file_t template = { 0 };

  pool_get (socket_main.registration_pool, rp);
  memset (rp, 0, sizeof (*rp));

  template.read_function = vl_socket_read_ready;
  template.write_function = vl_socket_write_ready;
  template.error_function = vl_socket_error_ready;
  template.file_descriptor = fd;
  template.private_data = rp - socket_main.registration_pool;

  rp->registration_type = REGISTRATION_TYPE_SOCKET_SERVER;
  rp->vl_api_registration_pool_index = rp - socket_main.registration_pool;
  rp->unix_file_index = unix_file_add (um, &template);
}

static clib_error_t *
socksvr_accept_ready (unix_file_t * uf)
{
  unix_main_t *um = &unix_main;
  struct sockaddr_in client_addr;
  int client_fd;
  int client_len;

  client_len = sizeof (client_addr);

  /*
   * Supposedly acquires the non-blocking attrib from the
   * server socket.
   */
  client_fd = accept (uf->file_descriptor,
		      (struct sockaddr *) &client_addr,
		      (socklen_t *) & client_len);

  if (client_fd < 0)
    return clib_error_return_unix (0, "socksvr_accept_ready: accept");

  socksvr_file_add (um, client_fd);
  return 0;
}

static clib_error_t *
socksvr_bogus_write (unix_file_t * uf)
{
  clib_warning ("why am I here?");
  return 0;
}

/*
 * vl_api_sockclnt_create_t_handler
 */
void
vl_api_sockclnt_create_t_handler (vl_api_sockclnt_create_t * mp)
{
  vl_api_registration_t *regp;
  vl_api_sockclnt_create_reply_t *rp;
  int rv = 1;

  regp = socket_main.current_rp;

  ASSERT (regp->registration_type == REGISTRATION_TYPE_SOCKET_SERVER);

  regp->name = format (0, "%s%c", mp->name, 0);

  rp = vl_msg_api_alloc (sizeof (*rp));
  rp->_vl_msg_id = htons (VL_API_SOCKCLNT_CREATE_REPLY);
  rp->handle = (uword) regp;
  rp->index = (uword) regp->vl_api_registration_pool_index;
  rp->context = mp->context;
  rp->response = htonl (rv);

  vl_msg_api_send (regp, (u8 *) rp);
}

/*
 * vl_api_sockclnt_delete_t_handler
 */
void
vl_api_sockclnt_delete_t_handler (vl_api_sockclnt_delete_t * mp)
{
  vl_api_registration_t *regp;
  vl_api_sockclnt_delete_reply_t *rp;

  if (!pool_is_free_index (socket_main.registration_pool, mp->index))
    {
      regp = pool_elt_at_index (socket_main.registration_pool, mp->index);

      rp = vl_msg_api_alloc (sizeof (*rp));
      rp->_vl_msg_id = htons (VL_API_SOCKCLNT_DELETE_REPLY);
      rp->handle = mp->handle;
      rp->response = htonl (1);

      vl_msg_api_send (regp, (u8 *) rp);

      unix_file_del (&unix_main, unix_main.file_pool + regp->unix_file_index);

      vl_free_socket_registration_index (mp->index);
    }
  else
    {
      clib_warning ("unknown client ID %d", mp->index);
    }
}

#define foreach_vlib_api_msg                    \
_(SOCKCLNT_CREATE, sockclnt_create)             \
_(SOCKCLNT_DELETE, sockclnt_delete)

static clib_error_t *
socksvr_api_init (vlib_main_t * vm)
{
  unix_main_t *um = &unix_main;
  unix_file_t template = { 0 };
  int sockfd;
  int one = 1;
  int rv;
  struct sockaddr_in serv_addr;
  vl_api_registration_t *rp;
  u16 portno;
  u32 bind_address;

#define _(N,n)                                                  \
    vl_msg_api_set_handlers(VL_API_##N, #n,                     \
                           vl_api_##n##_t_handler,              \
                           vl_noop_handler,                     \
                           vl_api_##n##_t_endian,               \
                           vl_api_##n##_t_print,                \
                           sizeof(vl_api_##n##_t), 1);
  foreach_vlib_api_msg;
#undef _

  vec_resize (socket_main.input_buffer, 4096);

  /* Set up non-blocking server socket on CLIENT_API_SERVER_PORT */
  sockfd = socket (AF_INET, SOCK_STREAM, 0);

  if (sockfd < 0)
    {
      return clib_error_return_unix (0, "socket");
    }

  rv = ioctl (sockfd, FIONBIO, &one);
  if (rv < 0)
    {
      close (sockfd);
      return clib_error_return_unix (0, "FIONBIO");
    }

  rv = setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof (one));
  if (rv < 0)
    {
      close (sockfd);
      return clib_error_return_unix (0, "SO_REUSEADDR");
    }

  bzero ((char *) &serv_addr, sizeof (serv_addr));
  serv_addr.sin_family = AF_INET;

  if (socket_main.bind_address)
    bind_address = socket_main.bind_address;
  else
    bind_address = INADDR_LOOPBACK;

  if (socket_main.portno)
    portno = socket_main.portno;
  else
    portno = SOCKSVR_DEFAULT_PORT;

  serv_addr.sin_port = clib_host_to_net_u16 (portno);
  serv_addr.sin_addr.s_addr = clib_host_to_net_u32 (bind_address);

  if (bind (sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0)
    {
      close (sockfd);
      return clib_error_return_unix (0, "bind");
    }

  rv = listen (sockfd, 5);
  if (rv < 0)
    {
      close (sockfd);
      return clib_error_return_unix (0, "listen");
    }

  pool_get (socket_main.registration_pool, rp);
  memset (rp, 0, sizeof (*rp));

  rp->registration_type = REGISTRATION_TYPE_SOCKET_LISTEN;

  template.read_function = socksvr_accept_ready;
  template.write_function = socksvr_bogus_write;
  template.file_descriptor = sockfd;
  template.private_data = rp - socket_main.registration_pool;

  rp->unix_file_index = unix_file_add (um, &template);
  return 0;
}

static clib_error_t *
socket_exit (vlib_main_t * vm)
{
  unix_main_t *um = &unix_main;
  vl_api_registration_t *rp;

  /* Defensive driving in case something wipes out early */
  if (socket_main.registration_pool)
    {
      u32 index;
        /* *INDENT-OFF* */
        pool_foreach (rp, socket_main.registration_pool, ({
            unix_file_del (um, um->file_pool + rp->unix_file_index);
            index = rp->vl_api_registration_pool_index;
            vl_free_socket_registration_index (index);
        }));
/* *INDENT-ON* */
    }

  return 0;
}

VLIB_MAIN_LOOP_EXIT_FUNCTION (socket_exit);

static clib_error_t *
socksvr_config (vlib_main_t * vm, unformat_input_t * input)
{
  int portno;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "port %d", &portno))
	{
	  socket_main.portno = portno;
	}
      else
	{
	  return clib_error_return (0, "unknown input '%U'",
				    format_unformat_error, input);
	}
    }
  return socksvr_api_init (vm);
}

VLIB_CONFIG_FUNCTION (socksvr_config, "socksvr");

/* argument in host byte order */
void
socksvr_set_port (u16 port)
{
  socket_main.portno = port;
}

/* argument in host byte order */
void
socksvr_set_bind_address (u32 bind_address)
{
  socket_main.bind_address = bind_address;
}

clib_error_t *
vlibsocket_init (vlib_main_t * vm)
{
  return 0;
}

VLIB_INIT_FUNCTION (vlibsocket_init);

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