Example #1
0
static void citp_passthrough_dtor(citp_fdinfo* fdi, int fdt_locked)
{
  citp_alien_fdi* epi = fdi_to_alien_fdi(fdi);

  CITP_FDTABLE_LOCK();
  ci_tcp_helper_close_no_trampoline(epi->os_socket);
  __citp_fdtable_reserve(epi->os_socket, 0);
  CITP_FDTABLE_UNLOCK();
  citp_netif_release_ref(fdi_to_alien_fdi(fdi)->netif, fdt_locked);
}
Example #2
0
int
citp_passthrough_accept(citp_fdinfo* fdi,
                        struct sockaddr* sa, socklen_t* p_sa_len, int flags,
                        citp_lib_context_t* lib_context)
{
#if CI_LIBC_HAS_accept4
  return ci_sys_accept4(fdi_to_alien_fdi(fdi)->os_socket,
                        sa, p_sa_len, flags);
#else
  ci_assert_equal(flags, 0);
  return ci_sys_accept(fdi_to_alien_fdi(fdi)->os_socket,
                        sa, p_sa_len);
#endif
}
Example #3
0
static int
citp_passthrough_getsockopt(citp_fdinfo* fdi, int level,
                            int optname, void* optval, socklen_t* optlen)
{
  return ci_sys_getsockopt(fdi_to_alien_fdi(fdi)->os_socket,
                           level, optname, optval, optlen);
}
Example #4
0
static int
citp_passthrough_getpeername(citp_fdinfo* fdi,
                             struct sockaddr* sa, socklen_t* p_sa_len)
{
  return ci_sys_getpeername(fdi_to_alien_fdi(fdi)->os_socket,
                            sa, p_sa_len);
}
Example #5
0
static int citp_passthrough_listen(citp_fdinfo* fdi, int backlog)
{
  int rc = ci_sys_listen(fdi_to_alien_fdi(fdi)->os_socket,
                         backlog);
  citp_fdinfo_release_ref(fdi, 0);
  return rc;
}
Example #6
0
static void citp_fdinfo_do_handover(citp_fdinfo* fdi, int fdt_locked)
{
  int rc;
  citp_fdinfo* epoll_fdi = NULL;
  int os_fd = fdi->fd;
#ifndef NDEBUG
  /* Yuk: does for UDP too. */
  volatile citp_fdinfo_p* p_fdip;
  p_fdip = &citp_fdtable.table[fdi->fd].fdip;
  ci_assert(fdip_is_busy(*p_fdip));
#endif


  Log_V(ci_log("%s: fd=%d nonb_switch=%d", __FUNCTION__, fdi->fd,
	       fdi->on_rcz.handover_nonb_switch));

  if( fdi->epoll_fd >= 0 ) {
    epoll_fdi = citp_epoll_fdi_from_member(fdi, fdt_locked);
    if( epoll_fdi->protocol->type == CITP_EPOLLB_FD )
      citp_epollb_on_handover(epoll_fdi, fdi);
  }
  rc = fdtable_fd_move(fdi->fd, OO_IOC_TCP_HANDOVER);
  if( rc == -EBUSY && fdi->epoll_fd >= 0 ) {
    ci_assert(fdi_to_sock_fdi(fdi)->sock.s->b.sb_aflags &
              CI_SB_AFLAG_MOVED_AWAY);
    /* If this is our epoll, we can do full handover: we manually add os
     * fd into the epoll set.
     * Fixme: ensure we are not in _other_ epoll sets */
    ci_bit_clear(&fdi_to_sock_fdi(fdi)->sock.s->b.sb_aflags,
                 CI_SB_AFLAG_MOVED_AWAY_IN_EPOLL_BIT);
    rc = fdtable_fd_move(fdi->fd, OO_IOC_FILE_MOVED);
  }
  if( rc != 0 ) {
    citp_fdinfo* new_fdi;
    if( ! fdt_locked ) CITP_FDTABLE_LOCK();
    new_fdi = citp_fdtable_probe_locked(fdi->fd, CI_TRUE, CI_TRUE);
    citp_fdinfo_release_ref(new_fdi, 1);
    if( ! fdt_locked ) CITP_FDTABLE_UNLOCK();
    ci_assert_equal(citp_fdinfo_get_type(new_fdi), CITP_PASSTHROUGH_FD);
    os_fd = fdi_to_alien_fdi(new_fdi)->os_socket;
  }
  if( fdi->on_rcz.handover_nonb_switch >= 0 ) {
    int on_off = !! fdi->on_rcz.handover_nonb_switch;
    int rc = ci_sys_ioctl(os_fd, FIONBIO, &on_off);
    if( rc < 0 )
      Log_E(ci_log("%s: ioctl failed on_off=%d", __FUNCTION__, on_off));
  }
  if( rc != 0 )
    goto exit;
  citp_fdtable_busy_clear(fdi->fd, fdip_passthru, fdt_locked);
exit:
  citp_fdinfo_get_ops(fdi)->dtor(fdi, fdt_locked);
  if( epoll_fdi != NULL && epoll_fdi->protocol->type == CITP_EPOLL_FD )
    citp_epoll_on_handover(epoll_fdi, fdi, fdt_locked);
  if( epoll_fdi != NULL )
    citp_fdinfo_release_ref(epoll_fdi, fdt_locked);
  citp_fdinfo_free(fdi);
}
Example #7
0
int
citp_passthrough_bind(citp_fdinfo* fdi,
                      const struct sockaddr* sa, socklen_t sa_len)
{
  int rc = ci_sys_bind(fdi_to_alien_fdi(fdi)->os_socket,
                       sa, sa_len);
  citp_fdinfo_release_ref(fdi, 0);
  return rc;
}
Example #8
0
static int
citp_passthrough_setsockopt(citp_fdinfo* fdi, int level, int optname,
                            const void* optval, socklen_t optlen)
{
  int rc = ci_sys_setsockopt(fdi_to_alien_fdi(fdi)->os_socket,
                             level, optname, optval, optlen);
  citp_fdinfo_release_ref(fdi, 0);
  return rc;
}
Example #9
0
static int
citp_passthrough_connect(citp_fdinfo* fdi,
                         const struct sockaddr* sa, socklen_t sa_len,
                         citp_lib_context_t* lib_context)
{
  int rc = ci_sys_connect(fdi_to_alien_fdi(fdi)->os_socket,
                          sa, sa_len);
  citp_fdinfo_release_ref(fdi, 0);
  return rc;
}
Example #10
0
static int
citp_passthrough_sendmmsg(citp_fdinfo* fdinfo, struct mmsghdr* mmsg, 
                          unsigned vlen, int flags)
{
#ifdef OO_SENDMMSG_NOT_IN_LIBC
  errno = ENOSYS;
  return -1;
#else
  return ci_sys_sendmmsg(fdi_to_alien_fdi(fdinfo)->os_socket,
                         mmsg, vlen, flags);
#endif
}
Example #11
0
static int
citp_passthrough_recvmmsg(citp_fdinfo* fdi, struct mmsghdr* msg, 
                          unsigned vlen, int flags,
                          ci_recvmmsg_timespec* timeout)
{
#ifdef OO_RECVMMSG_NOT_IN_LIBC
  errno = ENOSYS;
  return -1;
#else
  return ci_sys_recvmmsg(fdi_to_alien_fdi(fdi)->os_socket,
                         msg, vlen, flags, timeout);
#endif
}
Example #12
0
static int citp_passthrough_shutdown(citp_fdinfo* fdi, int how)
{
  return ci_sys_shutdown(fdi_to_alien_fdi(fdi)->os_socket, how);
}
Example #13
0
static int
citp_passthrough_ioctl(citp_fdinfo* fdi, int request, void* arg)
{
  return ci_sys_ioctl(fdi_to_alien_fdi(fdi)->os_socket,
                      request, arg);
}
Example #14
0
static int
citp_passthrough_send(citp_fdinfo* fdi, const struct msghdr* msg, int flags)
{
  return ci_sys_sendmsg(fdi_to_alien_fdi(fdi)->os_socket,
                        msg, flags);
}