Skip to content
Snippets Groups Projects
  • Stefan Hajnoczi's avatar
    8917c3bd
    slirp: switch to GPollFD · 8917c3bd
    Stefan Hajnoczi authored
    
    Slirp uses rfds/wfds/xfds more extensively than other QEMU components.
    
    The rarely-used out-of-band TCP data feature is used.  That means we
    need the full table of select(2) to g_poll(3) events:
    
      rfds -> G_IO_IN | G_IO_HUP | G_IO_ERR
      wfds -> G_IO_OUT | G_IO_ERR
      xfds -> G_IO_PRI
    
    I came up with this table by looking at Linux fs/select.c which maps
    select(2) to poll(2) internally.
    
    Another detail to watch out for are the global variables that reference
    rfds/wfds/xfds during slirp_select_poll().  sofcantrcvmore() and
    sofcantsendmore() use these globals to clear fd_set bits.  When
    sofcantrcvmore() is called, the wfds bit is cleared so that the write
    handler will no longer be run for this iteration of the event loop.
    
    This actually seems buggy to me since TCP connections can be half-closed
    and we'd still want to handle data in half-duplex fashion.  I think the
    real intention is to avoid running the read/write handler when the
    socket has been fully closed.  This is indicated with the SS_NOFDREF
    state bit so we now check for it before invoking the TCP write handler.
    Note that UDP/ICMP code paths don't care because they are
    connectionless.
    
    Note that slirp/ has a lot of tabs and sometimes mixed tabs with spaces.
    I followed the style of the surrounding code.
    
    Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
    Reviewed-by: default avatarLaszlo Ersek <lersek@redhat.com>
    Message-id: 1361356113-11049-6-git-send-email-stefanha@redhat.com
    Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
    8917c3bd
    History
    slirp: switch to GPollFD
    Stefan Hajnoczi authored
    
    Slirp uses rfds/wfds/xfds more extensively than other QEMU components.
    
    The rarely-used out-of-band TCP data feature is used.  That means we
    need the full table of select(2) to g_poll(3) events:
    
      rfds -> G_IO_IN | G_IO_HUP | G_IO_ERR
      wfds -> G_IO_OUT | G_IO_ERR
      xfds -> G_IO_PRI
    
    I came up with this table by looking at Linux fs/select.c which maps
    select(2) to poll(2) internally.
    
    Another detail to watch out for are the global variables that reference
    rfds/wfds/xfds during slirp_select_poll().  sofcantrcvmore() and
    sofcantsendmore() use these globals to clear fd_set bits.  When
    sofcantrcvmore() is called, the wfds bit is cleared so that the write
    handler will no longer be run for this iteration of the event loop.
    
    This actually seems buggy to me since TCP connections can be half-closed
    and we'd still want to handle data in half-duplex fashion.  I think the
    real intention is to avoid running the read/write handler when the
    socket has been fully closed.  This is indicated with the SS_NOFDREF
    state bit so we now check for it before invoking the TCP write handler.
    Note that UDP/ICMP code paths don't care because they are
    connectionless.
    
    Note that slirp/ has a lot of tabs and sometimes mixed tabs with spaces.
    I followed the style of the surrounding code.
    
    Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
    Reviewed-by: default avatarLaszlo Ersek <lersek@redhat.com>
    Message-id: 1361356113-11049-6-git-send-email-stefanha@redhat.com
    Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
main.h 1.13 KiB
/*
 * Copyright (c) 1995 Danny Gasparovski.
 *
 * Please read the file COPYRIGHT for the
 * terms and conditions of the copyright.
 */
#ifndef SLIRP_MAIN_H
#define SLIRP_MAIN_H 1

#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif

#define TOWRITEMAX 512

extern int slirp_socket;
extern int slirp_socket_unit;
extern int slirp_socket_port;
extern uint32_t slirp_socket_addr;
extern char *slirp_socket_passwd;
extern int ctty_closed;

/*
 * Get the difference in 2 times from updtim()
 * Allow for wraparound times, "just in case"
 * x is the greater of the 2 (current time) and y is
 * what it's being compared against.
 */
#define TIME_DIFF(x,y) (x)-(y) < 0 ? ~0-(y)+(x) : (x)-(y)

extern char *slirp_tty;
extern char *exec_shell;
extern u_int curtime;
extern struct in_addr loopback_addr;
extern unsigned long loopback_mask;
extern char *username;
extern char *socket_path;
extern int towrite_max;
extern int ppp_exit;
extern int tcp_keepintvl;

#define PROTO_SLIP 0x1
#ifdef USE_PPP
#define PROTO_PPP 0x2
#endif

int if_encap(Slirp *slirp, struct mbuf *ifm);
ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags);

#endif