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

#define _GNU_SOURCE
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/uio.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <fcntl.h>
#include <errno.h>

#include <socket.h>
#include <memif.h>

/* sends msg to socket */
static_fn int
memif_msg_send (int fd, memif_msg_t * msg, int afd)
{
  struct msghdr mh = { 0 };
  struct iovec iov[1];
  char ctl[CMSG_SPACE (sizeof (int))];
  int rv, err = MEMIF_ERR_SUCCESS;	/* 0 */

  iov[0].iov_base = (void *) msg;
  iov[0].iov_len = sizeof (memif_msg_t);
  mh.msg_iov = iov;
  mh.msg_iovlen = 1;

  if (afd > 0)
    {
      struct cmsghdr *cmsg;
      memset (&ctl, 0, sizeof (ctl));
      mh.msg_control = ctl;
      mh.msg_controllen = sizeof (ctl);
      cmsg = CMSG_FIRSTHDR (&mh);
      cmsg->cmsg_len = CMSG_LEN (sizeof (int));
      cmsg->cmsg_level = SOL_SOCKET;
      cmsg->cmsg_type = SCM_RIGHTS;
      memcpy (CMSG_DATA (cmsg), &afd, sizeof (int));
    }
  rv = sendmsg (fd, &mh, 0);
  if (rv < 0)
    err = memif_syscall_error_handler (errno);
  DBG ("Message type %u sent", msg->type);
  return err;
}

/* response from memif master - master is ready to handle next message */
static_fn int
memif_msg_enq_ack (memif_connection_t * c)
{
  memif_msg_queue_elt_t *e =
    (memif_msg_queue_elt_t *) malloc (sizeof (memif_msg_queue_elt_t));
  if (e == NULL)
    return memif_syscall_error_handler (errno);

  memset (&e->msg, 0, sizeof (e->msg));
  e->msg.type = MEMIF_MSG_TYPE_ACK;
  e->fd = -1;

  e->next = NULL;
  if (c->msg_queue == NULL)
    {
      c->msg_queue = e;
      return MEMIF_ERR_SUCCESS;	/* 0 */
    }

  memif_msg_queue_elt_t *cur = c->msg_queue;
  while (cur->next != NULL)
    {
      cur = cur->next;
    }
  cur->next = e;

  return MEMIF_ERR_SUCCESS;	/* 0 */
}

static_fn int
memif_msg_send_hello (int fd)
{
  libmemif_main_t *lm = &libmemif_main;
  memif_msg_t msg = { 0 };
  memif_msg_hello_t *h = &msg.hello;
  msg.type = MEMIF_MSG_TYPE_HELLO;
  h->min_version = MEMIF_VERSION;
  h->max_version = MEMIF_VERSION;
  h->max_s2m_ring = MEMIF_MAX_M2S_RING;
  h->max_m2s_ring = MEMIF_MAX_M2S_RING;
  h->max_region = MEMIF_MAX_REGION;
  h->max_log2_ring_size = MEMIF_MAX_LOG2_RING_SIZE;

  strncpy ((char *) h->name, lm->app_name, strlen (lm->app_name));

  /* msg hello is not enqueued but sent directly,
     because it is the first msg to be sent */
  return memif_msg_send (fd, &msg, -1);
}

/* send id and secret (optional) for interface identification */
static_fn int
memif_msg_enq_init (memif_connection_t * c)
{
  memif_msg_queue_elt_t *e =
    (memif_msg_queue_elt_t *) malloc (sizeof (memif_msg_queue_elt_t));
  if (e == NULL)
    return memif_syscall_error_handler (errno);
  memset (e, 0, sizeof (memif_msg_queue_elt_t));

  memset (&e->msg, 0, sizeof (e->msg));
  memif_msg_init_t *i = &e->msg.init;

  e->msg.type = MEMIF_MSG_TYPE_INIT;
  e->fd = -1;
  i->version = MEMIF_VERSION;
  i->id = c->args.interface_id;
  i->mode = c->args.mode;

  strncpy ((char *) i->name, (char *) c->args.instance_name,
	   strlen ((char *) c->args.instance_name));
  if (c->args.secret)
    strncpy ((char *) i->secret, (char *) c->args.secret, sizeof (i->secret));

  e->next = NULL;
  if (c->msg_queue == NULL)
    {
      c->msg_queue = e;
      return MEMIF_ERR_SUCCESS;	/* 0 */
    }

  memif_msg_queue_elt_t *cur = c->msg_queue;
  while (cur->next != NULL)
    {
      cur = cur->next;
    }
  cur->next = e;

  return MEMIF_ERR_SUCCESS;	/* 0 */
}

/* send information about region specified by region_index */
static_fn int
memif_msg_enq_add_region (memif_connection_t * c, uint8_t region_index)
{
  /* maybe check if region is valid? */
  memif_region_t *mr = &c->regions[region_index];

  memif_msg_queue_elt_t *e =
    (memif_msg_queue_elt_t *) malloc (sizeof (memif_msg_queue_elt_t));
  if (e == NULL)
    return memif_syscall_error_handler (errno);

  memset (&e->msg, 0, sizeof (e->msg));
  memif_msg_add_region_t *ar = &e->msg.add_region;

  e->msg.type = MEMIF_MSG_TYPE_ADD_REGION;
  e->fd = mr->fd;
  ar->index = region_index;
  ar->size = mr->region_size;

  e->next = NULL;
  if (c->msg_queue == NULL)
    {
      c->msg_queue = e;
      return MEMIF_ERR_SUCCESS;	/* 0 */
    }

  memif_msg_queue_elt_t *cur = c->msg_queue;
  while (cur->next != NULL)
    {
      cur = cur->next;
    }
  cur->next = e;

  return MEMIF_ERR_SUCCESS;	/* 0 */
}

/* send information about ring specified by direction (S2M | M2S) and index */
static_fn int
memif_msg_enq_add_ring (memif_connection_t * c, uint8_t index, uint8_t dir)
{
  memif_msg_queue_elt_t *e =
    (memif_msg_queue_elt_t *) malloc (sizeof (memif_msg_queue_elt_t));
  if (e == NULL)
    return memif_syscall_error_handler (errno);

  memset (&e->msg, 0, sizeof (e->msg));
  memif_msg_add_ring_t *ar = &e->msg.add_ring;

  e->msg.type = MEMIF_MSG_TYPE_ADD_RING;

  /* TODO: support multiple rings */
  memif_queue_t *mq;
  if (dir == MEMIF_RING_M2S)
    mq = &c->rx_queues[index];
  else
    mq = &c->tx_queues[index];

  e->fd = mq->int_fd;
  ar->index = index;
  ar->offset = mq->offset;
  ar->region = mq->region;
  ar->log2_ring_size = mq->log2_ring_size;
  ar->flags = (dir == MEMIF_RING_S2M) ? MEMIF_MSG_ADD_RING_FLAG_S2M : 0;

  e->next = NULL;
  if (c->msg_queue == NULL)
    {
      c->msg_queue = e;
      return MEMIF_ERR_SUCCESS;	/* 0 */
    }

  memif_msg_queue_elt_t *cur = c->msg_queue;
  while (cur->next != NULL)
    {
      cur = cur->next;
    }
  cur->next = e;

  return MEMIF_ERR_SUCCESS;	/* 0 */
}

/* used as connection request from slave */
static_fn int
memif_msg_enq_connect (memif_connection_t * c)
{
  memif_msg_queue_elt_t *e =
    (memif_msg_queue_elt_t *) malloc (sizeof (memif_msg_queue_elt_t));
  if (e == NULL)
    return memif_syscall_error_handler (errno);

  memset (&e->msg, 0, sizeof (e->msg));
  memif_msg_connect_t *cm = &e->msg.connect;

  e->msg.type = MEMIF_MSG_TYPE_CONNECT;
  e->fd = -1;
  strncpy ((char *) cm->if_name, (char *) c->args.interface_name,
	   strlen ((char *) c->args.interface_name));

  e->next = NULL;
  if (c->msg_queue == NULL)
    {
      c->msg_queue = e;
      return MEMIF_ERR_SUCCESS;	/* 0 */
    }

  memif_msg_queue_elt_t *cur = c->msg_queue;
  while (cur->next != NULL)
    {
      cur = cur->next;
    }
  cur->next = e;

  return MEMIF_ERR_SUCCESS;	/* 0 */
}

/* used as confirmation of connection by master */
static_fn int
memif_msg_enq_connected (memif_connection_t * c)
{
  memif_msg_queue_elt_t *e =
    (memif_msg_queue_elt_t *) malloc (sizeof (memif_msg_queue_elt_t));
  if (e == NULL)
    return memif_syscall_error_handler (errno);

  memset (&e->msg, 0, sizeof (e->msg));
  memif_msg_connected_t *cm = &e->msg.connected;

  e->msg.type = MEMIF_MSG_TYPE_CONNECTED;
  e->fd = -1;
  strncpy ((char *) cm->if_name, (char *) c->args.interface_name,
	   strlen ((char *) c->args.interface_name));

  e->next = NULL;
  if (c->msg_queue == NULL)
    {
      c->msg_queue = e;
      return MEMIF_ERR_SUCCESS;	/* 0 */
    }

  memif_msg_queue_elt_t *cur = c->msg_queue;
  while (cur->next != NULL)
    {
      cur = cur->next;
    }
  cur->next = e;

  return MEMIF_ERR_SUCCESS;	/* 0 */
}

/* immediately send disconnect msg */
    /* specifie protocol for disconnect msg err_code
       so that it will be compatible with VPP? (header/doc) */
int
memif_msg_send_disconnect (int fd, uint8_t * err_string, uint32_t err_code)
{
  memif_msg_t msg = { 0 };
  memif_msg_disconnect_t *d = &msg.disconnect;

  msg.type = MEMIF_MSG_TYPE_DISCONNECT;
  d->code = err_code;
  uint16_t l = strlen ((char *) err_string);
  if (l > 96)
    {
      DBG ("Disconnect string too long. Sending first 96 characters.");
      l = 96;
    }
  strncpy ((char *) d->string, (char *) err_string, l);

  return memif_msg_send (fd, &msg, -1);
}

static_fn int
memif_msg_receive_hello (memif_connection_t * c, memif_msg_t * msg)
{
  memif_msg_hello_t *h = &msg->hello;

  if (msg->hello.min_version > MEMIF_VERSION ||
      msg->hello.max_version < MEMIF_VERSION)
    {
      DBG ("incompatible protocol version");
      return MEMIF_ERR_PROTO;
    }

  c->run_args.num_s2m_rings = memif_min (h->max_s2m_ring + 1,
					 c->args.num_s2m_rings);
  c->run_args.num_m2s_rings = memif_min (h->max_m2s_ring + 1,
					 c->args.num_m2s_rings);
  c->run_args.log2_ring_size = memif_min (h->max_log2_ring_size,
					  c->args.log2_ring_size);
  c->run_args.buffer_size = c->args.buffer_size;
  strncpy ((char *) c->remote_name, (char *) h->name,
	   strlen ((char *) h->name));

  return MEMIF_ERR_SUCCESS;	/* 0 */
}

/* handle interface identification (id, secret (optional)) */
static_fn int
memif_msg_receive_init (memif_socket_t * ms, int fd, memif_msg_t * msg)
{
  memif_msg_init_t *i = &msg->init;
  memif_list_elt_t *elt = NULL;
  memif_list_elt_t elt2;
  memif_connection_t *c = NULL;
  libmemif_main_t *lm = &libmemif_main;
  uint8_t err_string[96];
  memset (err_string, 0, sizeof (char) * 96);
  int err = MEMIF_ERR_SUCCESS;	/* 0 */
  int err_disc;
  if (i->version != MEMIF_VERSION)
    {
      DBG ("MEMIF_VER_ERR");
      strncpy ((char *) err_string, MEMIF_VER_ERR, strlen (MEMIF_VER_ERR));
      err = MEMIF_ERR_PROTO;
      goto error;
    }

  get_list_elt (&elt, ms->interface_list, ms->interface_list_len, i->id);
  if (elt == NULL)
    {
      DBG ("MEMIF_ID_ERR");
      strncpy ((char *) err_string, MEMIF_ID_ERR, strlen (MEMIF_ID_ERR));
      err = MEMIF_ERR_ID;
      goto error;
    }

  c = (memif_connection_t *) elt->data_struct;

  if (!(c->args.is_master))
    {
      DBG ("MEMIF_SLAVE_ERR");
      strncpy ((char *) err_string, MEMIF_SLAVE_ERR,
	       strlen (MEMIF_SLAVE_ERR));
      err = MEMIF_ERR_ACCSLAVE;
      goto error;
    }
  if (c->fd != -1)
    {
      DBG ("MEMIF_CONN_ERR");
      strncpy ((char *) err_string, MEMIF_CONN_ERR, strlen (MEMIF_CONN_ERR));
      err = MEMIF_ERR_ALRCONN;
      goto error;
    }

  c->fd = fd;

  if (i->mode != c->args.mode)
    {
      DBG ("MEMIF_MODE_ERR");
      strncpy ((char *) err_string, MEMIF_MODE_ERR, strlen (MEMIF_MODE_ERR));
      err = MEMIF_ERR_MODE;
      goto error;
    }

  strncpy ((char *) c->remote_name, (char *) i->name,
	   strlen ((char *) i->name));

  if (c->args.secret)
    {
      int r;
      if (i->secret)
	{
	  if (strlen ((char *) c->args.secret) != strlen ((char *) i->secret))
	    {
	      DBG ("MEMIF_SECRET_ERR");
	      strncpy ((char *) err_string,
		       MEMIF_SECRET_ERR, strlen (MEMIF_SECRET_ERR));
	      err = MEMIF_ERR_SECRET;
	      goto error;
	    }
	  r = strncmp ((char *) i->secret, (char *) c->args.secret,
		       strlen ((char *) c->args.secret));
	  if (r != 0)
	    {
	      DBG ("MEMIF_SECRET_ERR");
	      strncpy ((char *) err_string,
		       MEMIF_SECRET_ERR, strlen (MEMIF_SECRET_ERR));
	      err = MEMIF_ERR_SECRET;
	      goto error;
	    }
	}
      else
	{
	  DBG ("MEMIF_NOSECRET_ERR");
	  strncpy ((char *) err_string,
		   MEMIF_NOSECRET_ERR, strlen (MEMIF_NOSECRET_ERR));
	  err = MEMIF_ERR_NOSECRET;
	  goto error;
	}
    }

  c->read_fn = memif_conn_fd_read_ready;
  c->write_fn = memif_conn_fd_write_ready;
  c->error_fn = memif_conn_fd_error;

  elt2.key = c->fd;
  elt2.data_struct = c;

  add_list_elt (&elt2, &lm->control_list, &lm->control_list_len);
  free_list_elt (lm->pending_list, lm->pending_list_len, fd);

  return err;

error:
  memif_msg_send_disconnect (fd, err_string, 0);
  lm->control_fd_update (fd, MEMIF_FD_EVENT_DEL);
  free_list_elt (lm->pending_list, lm->pending_list_len, fd);
  close (fd);
  fd = -1;
  return err;
}

/* receive region information and add new region to connection (if possible) */
static_fn int
memif_msg_receive_add_region (memif_connection_t * c, memif_msg_t * msg,
			      int fd)
{
  memif_msg_add_region_t *ar = &msg->add_region;
  memif_region_t *mr;
  if (fd < 0)
    return MEMIF_ERR_NO_SHMFD;

  if (ar->index > MEMIF_MAX_REGION)
    return MEMIF_ERR_MAXREG;

  mr =
    (memif_region_t *) realloc (c->regions,
				sizeof (memif_region_t) * (ar->index + 1));
  if (mr == NULL)
    return memif_syscall_error_handler (errno);
  c->regions = mr;
  c->regions[ar->index].fd = fd;
  c->regions[ar->index].region_size = ar->size;
  c->regions[ar->index].shm = NULL;

  return MEMIF_ERR_SUCCESS;	/* 0 */
}

/* receive ring information and add new ring to connection queue
   (based on direction S2M | M2S) */
static_fn int
memif_msg_receive_add_ring (memif_connection_t * c, memif_msg_t * msg, int fd)
{
  memif_msg_add_ring_t *ar = &msg->add_ring;

  memif_queue_t *mq;

  if (fd < 0)
    return MEMIF_ERR_NO_INTFD;

  if (ar->flags & MEMIF_MSG_ADD_RING_FLAG_S2M)
    {
      if (ar->index > MEMIF_MAX_S2M_RING)
	return MEMIF_ERR_MAXRING;
      if (ar->index >= c->args.num_s2m_rings)
	return MEMIF_ERR_MAXRING;

      mq =
	(memif_queue_t *) realloc (c->rx_queues,
				   sizeof (memif_queue_t) * (ar->index + 1));
	memset(mq, 0, sizeof (memif_queue_t) * (ar->index + 1));
      if (mq == NULL)
	return memif_syscall_error_handler (errno);
      c->rx_queues = mq;
      c->rx_queues[ar->index].int_fd = fd;
      c->rx_queues[ar->index].log2_ring_size = ar->log2_ring_size;
      c->rx_queues[ar->index].region = ar->region;
      c->rx_queues[ar->index].offset = ar->offset;
      c->run_args.num_s2m_rings++;
    }
  else
    {
      if (ar->index > MEMIF_MAX_M2S_RING)
	return MEMIF_ERR_MAXRING;
      if (ar->index >= c->args.num_m2s_rings)
	return MEMIF_ERR_MAXRING;

      mq =
	(memif_queue_t *) realloc (c->tx_queues,
				   sizeof (memif_queue_t) * (ar->index + 1));
	memset(mq, 0, sizeof (memif_queue_t) * (ar->index + 1));
      if (mq == NULL)
	return memif_syscall_error_handler (errno);
      c->tx_queues = mq;
      c->tx_queues[ar->index].int_fd = fd;
      c->tx_queues[ar->index].log2_ring_size = ar->log2_ring_size;
      c->tx_queues[ar->index].region = ar->region;
      c->tx_queues[ar->index].offset = ar->offset;
      c->run_args.num_m2s_rings++;
    }

  return MEMIF_ERR_SUCCESS;	/* 0 */
}

/* slave -> master */
static_fn int
memif_msg_receive_connect (memif_connection_t * c, memif_msg_t * msg)
{
  memif_msg_connect_t *cm = &msg->connect;
  libmemif_main_t *lm = &libmemif_main;
  memif_list_elt_t elt;

  int err;
  err = memif_connect1 (c);
  if (err != MEMIF_ERR_SUCCESS)
    return err;

  strncpy ((char *) c->remote_if_name, (char *) cm->if_name,
	   strlen ((char *) cm->if_name));

  int i;
  if (c->on_interrupt != NULL)
    {
      for (i = 0; i < c->run_args.num_m2s_rings; i++)
	{
	  elt.key = c->rx_queues[i].int_fd;
	  elt.data_struct = c;
	  add_list_elt (&elt, &lm->interrupt_list, &lm->interrupt_list_len);

	  lm->control_fd_update (c->rx_queues[i].int_fd, MEMIF_FD_EVENT_READ);
	}

    }

  c->on_connect ((void *) c, c->private_ctx);

  return err;
}

/* master -> slave */
static_fn int
memif_msg_receive_connected (memif_connection_t * c, memif_msg_t * msg)
{
  memif_msg_connect_t *cm = &msg->connect;
  libmemif_main_t *lm = &libmemif_main;

  int err;
  err = memif_connect1 (c);
  if (err != MEMIF_ERR_SUCCESS)
    return err;

  strncpy ((char *) c->remote_if_name, (char *) cm->if_name,
	   strlen ((char *) cm->if_name));

  int i;
  if (c->on_interrupt != NULL)
    {
      for (i = 0; i < c->run_args.num_s2m_rings; i++)
	lm->control_fd_update (c->rx_queues[i].int_fd, MEMIF_FD_EVENT_READ);
    }

  c->on_connect ((void *) c, c->private_ctx);

  return err;
}

static_fn int
memif_msg_receive_disconnect (memif_connection_t * c, memif_msg_t * msg)
{
  memif_msg_disconnect_t *d = &msg->disconnect;

  memset (c->remote_disconnect_string, 0,
	  sizeof (c->remote_disconnect_string));
  strncpy ((char *) c->remote_disconnect_string, (char *) d->string,
	   strlen ((char *) d->string));

  /* on returning error, handle function will call memif_disconnect () */
  DBG ("disconnect received: %s, mode: %d",
       c->remote_disconnect_string, c->args.mode);
  return MEMIF_ERR_DISCONNECT;
}

static_fn int
memif_msg_receive (int ifd)
{
  char ctl[CMSG_SPACE (sizeof (int)) +
	   CMSG_SPACE (sizeof (struct ucred))] = { 0 };
  struct msghdr mh = { 0 };
  struct iovec iov[1];
  memif_msg_t msg = { 0 };
  ssize_t size;
  int err = MEMIF_ERR_SUCCESS;	/* 0 */
  int fd = -1;
  int i;
  libmemif_main_t *lm = &libmemif_main;
  memif_connection_t *c = NULL;
  memif_socket_t *ms = NULL;
  memif_list_elt_t *elt = NULL;

  iov[0].iov_base = (void *) &msg;
  iov[0].iov_len = sizeof (memif_msg_t);
  mh.msg_iov = iov;
  mh.msg_iovlen = 1;
  mh.msg_control = ctl;
  mh.msg_controllen = sizeof (ctl);

  DBG ("recvmsg fd %d", ifd);
  size = recvmsg (ifd, &mh, 0);
  DBG ("done");
  if (size != sizeof (memif_msg_t))
    {
      if (size == 0)
	return MEMIF_ERR_DISCONNECTED;
      else
	return MEMIF_ERR_MFMSG;
    }

  struct ucred *cr = 0;
  struct cmsghdr *cmsg;

  cmsg = CMSG_FIRSTHDR (&mh);
  while (cmsg)
    {
      if (cmsg->cmsg_level == SOL_SOCKET)
	{
	  if (cmsg->cmsg_type == SCM_CREDENTIALS)
	    {
	      cr = (struct ucred *) CMSG_DATA (cmsg);
	    }
	  else if (cmsg->cmsg_type == SCM_RIGHTS)
	    {
	      int *fdp = (int *) CMSG_DATA (cmsg);
	      fd = *fdp;
	    }
	}
      cmsg = CMSG_NXTHDR (&mh, cmsg);
    }

  DBG ("Message type %u received", msg.type);

  get_list_elt (&elt, lm->control_list, lm->control_list_len, ifd);
  if (elt != NULL)
    c = (memif_connection_t *) elt->data_struct;

  switch (msg.type)
    {
    case MEMIF_MSG_TYPE_ACK:
      break;

    case MEMIF_MSG_TYPE_HELLO:
      if ((err = memif_msg_receive_hello (c, &msg)) != MEMIF_ERR_SUCCESS)
	return err;
      if ((err = memif_init_regions_and_queues (c)) != MEMIF_ERR_SUCCESS)
	return err;
      if ((err = memif_msg_enq_init (c)) != MEMIF_ERR_SUCCESS)
	return err;
      if ((err = memif_msg_enq_add_region (c, 0)) != MEMIF_ERR_SUCCESS)
	return err;
      for (i = 0; i < c->run_args.num_s2m_rings; i++)
	{
	  if ((err =
	       memif_msg_enq_add_ring (c, i,
				       MEMIF_RING_S2M)) != MEMIF_ERR_SUCCESS)
	    return err;
	}
      for (i = 0; i < c->run_args.num_m2s_rings; i++)
	{
	  if ((err =
	       memif_msg_enq_add_ring (c, i,
				       MEMIF_RING_M2S)) != MEMIF_ERR_SUCCESS)
	    return err;
	}
      if ((err = memif_msg_enq_connect (c)) != MEMIF_ERR_SUCCESS)
	return err;
      break;

    case MEMIF_MSG_TYPE_INIT:
      get_list_elt (&elt, lm->pending_list, lm->pending_list_len, ifd);
      if (elt == NULL)
	return -1;
      ms = (memif_socket_t *) elt->data_struct;
      if ((err = memif_msg_receive_init (ms, ifd, &msg)) != MEMIF_ERR_SUCCESS)
	return err;
      /* c->remote_pid = cr->pid */
      /* c->remote_uid = cr->uid */
      /* c->remote_gid = cr->gid */
      get_list_elt (&elt, lm->control_list, lm->control_list_len, ifd);
      if (elt == NULL)
	return -1;
      c = (memif_connection_t *) elt->data_struct;
      if ((err = memif_msg_enq_ack (c)) != MEMIF_ERR_SUCCESS)
	return err;
      break;

    case MEMIF_MSG_TYPE_ADD_REGION:
      if ((err =
	   memif_msg_receive_add_region (c, &msg, fd)) != MEMIF_ERR_SUCCESS)
	return err;
      if ((err = memif_msg_enq_ack (c)) != MEMIF_ERR_SUCCESS)
	return err;
      break;

    case MEMIF_MSG_TYPE_ADD_RING:
      if ((err =
	   memif_msg_receive_add_ring (c, &msg, fd)) != MEMIF_ERR_SUCCESS)
	return err;
      if ((err = memif_msg_enq_ack (c)) != MEMIF_ERR_SUCCESS)
	return err;
      break;

    case MEMIF_MSG_TYPE_CONNECT:
      if ((err = memif_msg_receive_connect (c, &msg)) != MEMIF_ERR_SUCCESS)
	return err;
      if ((err = memif_msg_enq_connected (c)) != MEMIF_ERR_SUCCESS)
	return err;
      break;

    case MEMIF_MSG_TYPE_CONNECTED:
      if ((err = memif_msg_receive_connected (c, &msg)) != MEMIF_ERR_SUCCESS)
	return err;
      break;

    case MEMIF_MSG_TYPE_DISCONNECT:
      if ((err = memif_msg_receive_disconnect (c, &msg)) != MEMIF_ERR_SUCCESS)
	return err;
      break;

    default:
      return MEMIF_ERR_UNKNOWN_MSG;;
      break;
    }

  if (c != NULL)
    c->flags |= MEMIF_CONNECTION_FLAG_WRITE;
/*    libmemif_main_t *lm = &libmemif_main;
    lm->control_fd_update (c->fd, MEMIF_FD_EVENT_READ | MEMIF_FD_EVENT_MOD); */
  return MEMIF_ERR_SUCCESS;	/* 0 */
}

int
memif_conn_fd_error (memif_connection_t * c)
{
  DBG ("connection fd error");
  strncpy ((char *) c->remote_disconnect_string, "connection fd error", 19);
  int err = memif_disconnect_internal (c);
  return err;
}

/* calls memif_msg_receive to handle pending messages on socket */
int
memif_conn_fd_read_ready (memif_connection_t * c)
{
  int err;
  err = memif_msg_receive (c->fd);
  if (err != 0)
    {
      err = memif_disconnect_internal (c);
    }
  return err;
}

/* get msg from msg queue buffer and send it to socket */
int
memif_conn_fd_write_ready (memif_connection_t * c)
{
  int err = MEMIF_ERR_SUCCESS;	/* 0 */


  if ((c->flags & MEMIF_CONNECTION_FLAG_WRITE) == 0)
    goto done;

  memif_msg_queue_elt_t *e = c->msg_queue;
  if (e == NULL)
    goto done;

  c->msg_queue = c->msg_queue->next;

  c->flags &= ~MEMIF_CONNECTION_FLAG_WRITE;
/*
    libmemif_main_t *lm = &libmemif_main;

    lm->control_fd_update (c->fd,
        MEMIF_FD_EVENT_READ | MEMIF_FD_EVENT_WRITE | MEMIF_FD_EVENT_MOD);
*/
  err = memif_msg_send (c->fd, &e->msg, e->fd);
  free (e);
  goto done;

done:
  return err;
}

int
memif_conn_fd_accept_ready (memif_socket_t * ms)
{
  int addr_len;
  struct sockaddr_un client;
  int conn_fd;
  libmemif_main_t *lm = &libmemif_main;

  DBG ("accept called");

  addr_len = sizeof (client);
  conn_fd =
    accept (ms->fd, (struct sockaddr *) &client, (socklen_t *) & addr_len);

  if (conn_fd < 0)
    {
      return memif_syscall_error_handler (errno);
    }
  DBG ("accept fd %d", ms->fd);
  DBG ("conn fd %d", conn_fd);

  memif_list_elt_t elt;
  elt.key = conn_fd;
  elt.data_struct = ms;

  add_list_elt (&elt, &lm->pending_list, &lm->pending_list_len);
  lm->control_fd_update (conn_fd, MEMIF_FD_EVENT_READ | MEMIF_FD_EVENT_WRITE);

  return memif_msg_send_hello (conn_fd);
}

int
memif_read_ready (int fd)
{
  int err;
  DBG ("call recv");
  err = memif_msg_receive (fd);
  DBG ("recv finished");
  return err;
}
