Beispiel #1
0
void
unixfd::newfd (svccb *sbp)
{
  assert (paios_out);

  rexcb_newfd_arg *argp = sbp->Xtmpl getarg<rexcb_newfd_arg> ();
    
  int s[2];
    
  if(socketpair(AF_UNIX, SOCK_STREAM, 0, s)) {
    warn << "error creating socketpair";
    sbp->replyref (false);
    return;
  }
    
  make_async (s[1]);
  make_async (s[0]);
  close_on_exec (s[1]);
  close_on_exec (s[0]);
    
  paios_out->sendfd (s[1]);
    
  vNew refcounted<unixfd> (pch, argp->newfd, s[0]);
  sbp->replyref (true);
}
Beispiel #2
0
/* unixfd specific arguments:

   localfd_in:	local file descriptor for input (or everything for non-tty)

   localfd_out: local file descriptor for output (only used for tty support)
     Set localfd_out = -1 (or omit the argument entirely) if you're not
     working with a remote tty; then the localfd_in is connected directly
     to the remote FD for both reads and writes (except it it's RO or WO).

   noclose: Unixfd will not use close or shutdown calls on the local
     file descriptor (localfd_in); useful for terminal descriptors,
     which must hang around so that raw mode can be disabled, etc.

   shutrdonexit: When the remote module exits, we shutdown the read
     direction of the local file descriptor (_in).  This isn't always
     done since not all file descriptors managed on the REX channel
     are necessarily connected to the remote module.
*/
unixfd::unixfd (rexchannel *pch, int fd, int localfd_in, int localfd_out,
		bool noclose, bool shutrdonexit, cbv closecb)
  : rexfd::rexfd (pch, fd),
    localfd_in (localfd_in), localfd_out (localfd_out), rsize (0),
    unixsock (isunixsocket (localfd_in)), weof (false), reof (false),
    shutrdonexit (shutrdonexit), closecb (closecb)
{
  if (noclose) {
    int duplocalfd = dup (localfd_in);
    if (duplocalfd < 0)
      warn ("failed to duplicate fd for noclose behavior (%m)\n");
    else
      unixfd::localfd_in = duplocalfd;
  }

  make_async (this->localfd_in);
  if (!is_fd_wronly (this->localfd_in))
    fdcb (this->localfd_in, selread, wrap (this, &unixfd::rcb));
    
  /* for tty support we split the input/output to two local FDs */
  if (localfd_out >= 0)
    paios_out = aios::alloc (this->localfd_out);
  else
    paios_out = aios::alloc (this->localfd_in);
}
Beispiel #3
0
static PyObject *
Core_fdcb (PyObject *self, PyObject *args)
{
  int fd = 0;
  int i_op = 0;
  PyObject *cb = NULL;

  if (!PyArg_ParseTuple (args, "ii|O", &fd, &i_op, &cb))
    return NULL;

  selop op = selop (i_op);

  if (op != selread && op != selwrite) {
    PyErr_SetString (PyExc_TypeError, "unknown select option");
    return NULL;
  }

  if (!cb) {
    fdcb (fd, op, NULL);
  } else {
    if (!PyCallable_Check (cb)) {
      PyErr_SetString (PyExc_TypeError, "callable object expected");
      return NULL;
    }
    ptr<pop_t> pop = pop_t::alloc (cb);
    make_async (fd);
    fdcb (fd, op, wrap (Core_cb, pop));
  }

  Py_INCREF (Py_None);
  return Py_None;
}
Beispiel #4
0
void
tcp_manager::doRPC_tcp_connect_cb (RPC_delay_args *args, int fd)
{

  hostinfo *hi = lookup_host (args->l->address ());
  if (fd < 0) {
    warn << "locationtable: connect failed: " << strerror (errno) << "\n";
    (args->cb) (RPC_CANTSEND);
    args->l->set_alive (false);
    remove_host (hi);
    delete args;
  }
  else {
    struct linger li;
    li.l_onoff = 1;
    li.l_linger = 0;
    setsockopt (fd, SOL_SOCKET, SO_LINGER, (char *) &li, sizeof (li));
    tcp_nodelay (fd);
    make_async(fd);
    hi->fd = fd;
    hi->xp = axprt_stream::alloc (fd);
    assert (hi->xp);
    send_RPC (args);
    while (hi->connect_waiters.size ())
      send_RPC (hi->connect_waiters.pop_front ());
  }
}
Beispiel #5
0
proxy::proxy (int fd1, int fd2)
{
    con[0].fd = fd1;
    con[1].fd = fd2;
    for (int i = 0; i < 2; i++) {
        make_async (con[i].fd);
        tcp_nodelay (con[i].fd);
        setcb (i);
    }
}
Beispiel #6
0
void
identptr (int fd, callback<void, str, ptr<hostent>, int>::ref cb)
{
  struct sockaddr_in la, ra;
  socklen_t len;

  len = sizeof (la);
  bzero (&la, sizeof (la));
  bzero (&ra, sizeof (ra));
  errno = 0;
  if (getsockname (fd, (struct sockaddr *) &la, &len) < 0
      || la.sin_family != AF_INET
      || getpeername (fd, (struct sockaddr *) &ra, &len) < 0
      || ra.sin_family != AF_INET
      || len != sizeof (la)) {
    warn ("ident: getsockname/getpeername: %s\n", strerror (errno));
    (*cb) ("*disconnected*", NULL, ARERR_CANTSEND);
    return;
  }

  u_int lp = ntohs (la.sin_port);
  la.sin_port = htons (0);
  u_int rp = ntohs (ra.sin_port);
  ra.sin_port = htons (AUTH_PORT);

  int ifd = socket (AF_INET, SOCK_STREAM, 0);
  if (ifd >= 0) {
    close_on_exec (ifd);
    make_async (ifd);
    if (connect (ifd, (sockaddr *) &ra, sizeof (ra)) < 0
	&& errno != EINPROGRESS) {
      close (ifd);
      ifd = -1;
    }
  }

  identstat *is = New identstat;
  is->err = 0;
  is->cb = cb;
  is->host = inet_ntoa (ra.sin_addr);

  if (ifd >= 0) {
    is->ncb = 2;
    close_on_exec (ifd);
    is->a = aios::alloc (ifd);
    is->a << rp << ", " << lp << "\r\n";
    is->a->settimeout (15);
    is->a->readline (wrap (is, &identstat::identcb));
  }
  else
    is->ncb = 1;

  dns_hostbyaddr (ra.sin_addr, wrap (is, &identstat::dnscb));
}
Beispiel #7
0
ptr<aclnt>
dhblock_srv::get_maint_aclnt (str msock)
{
  int fd = unixsocket_connect (msock);
  if (fd < 0)
    fatal ("get_maint_aclnt: Error connecting to %s: %m\n", msock.cstr ());
  make_async (fd);
  ptr<aclnt> c = aclnt::alloc (axprt_unix::alloc (fd, 1024*1025),
      maint_program_1);
  return c;
}
Beispiel #8
0
mtd_thread_arg_t *
mtdispatch_t::launch_init (int i, int fdout, int *closeit)
{
  int fds[2];
  if (pipe (fds) < 0)
    fatal << "mtdispatch::launch: cannot open pipe\n";
  make_async ((shmem->arr[i].fdout = fds[1]));
  mtd_thread_arg_t *arg = New mtd_thread_arg_t (i, fds[0], fdout, 
						&shmem->arr[i], this);
  *closeit = fds[0];
  return arg;
}
Beispiel #9
0
static PyObject *
Core_make_async (PyObject *self, PyObject *args)
{
  int fd = 0;

  if (!PyArg_ParseTuple (args, "i", &fd))
    return NULL;

  make_async (fd);

  Py_INCREF (Py_None);
  return Py_None;
}
Beispiel #10
0
void
sfs_unixserv (str sock, cbi cb, mode_t mode)
{
  /* We set the permissions of the socket because on some OS's this
   * gives an extra measure of protection.  However, the real
   * protection comes from the fact that sfssockdir is not world
   * readable or executable. */
  mode_t m = runinplace ? umask (0) : umask (~(mode & 0777));

  int lfd = unixsocket (sock);
  if (lfd < 0 && errno == EADDRINUSE) {
    /* XXX - This is a slightly race-prone way of cleaning up after a
     * server bails without unlinking the socket.  If we can't connect
     * to the socket, it's dead and should be unlinked and rebound.
     * Two daemons's could do this simultaneously, however. */
    int fd = unixsocket_connect (sock);
    if (fd < 0) {
      unlink (sock);
      lfd = unixsocket (sock);
    }
    else {
      close (fd);
      errno = EADDRINUSE;
    }
  }
  if (lfd < 0)
    fatal ("%s: %m\n", sock.cstr ());

  sockets.push_back (sock);

  umask (m);

  listen (lfd, 5);
  make_async (lfd);
  fdcb (lfd, selread, wrap (accept_cb, lfd, cb));

#if 0  /* A nice idea that unfortunately doesn't work... */
  struct stat sb1, sb2;
  if (stat (sock, &sb1) < 0 || fstat (lfd, &sb2) < 0)
    fatal ("%s: %m\n", sock);
  if (sb1.st_ino != sb2.st_ino || sb1.st_dev != sb2.st_dev)
    fatal ("%s: changed while binding\n", sock);
#endif
}
bool
resolver::tcpinit ()
{
  tcpsock = NULL;
  int fd = socket (addr->sa_family, SOCK_STREAM, 0);
  if (fd < 0) {
    warn ("resolver::tcpsock: socket: %m\n");
    return false;
  }
  make_async (fd);
  close_on_exec (fd);
  if (connect (fd, addr, addrlen) < 0 && errno != EINPROGRESS) {
    close (fd);
    return false;
  }
  tcpsock = New refcounted<dnssock_tcp> (fd, wrap (this, &resolver::pktready,
						   true));
  return true;
}
Beispiel #12
0
void
axprt_dgram::poll ()
{
  assert (cb);

  make_sync (fd);

  socklen_t ss = socksize;
  bzero (sabuf, ss);
  ssize_t ps = recvfrom (fd, pktbuf, pktsize, 0, sabuf, &ss);

  make_async (fd);

  if (ps < 0) {
    if (errno != EAGAIN && connected)
      (*cb) (NULL, -1, NULL);
    return;
  }
  (*cb) (pktbuf, ps, sabuf);
}
bool
resolver::udpinit ()
{
  udpsock = NULL;
  int fd = socket (addr->sa_family, SOCK_DGRAM, 0);
  if (fd < 0) {
    warn ("resolver::udpsock: socket: %m\n");
    return false;
  }
  make_async (fd);
  close_on_exec (fd);
  if (connect (fd, addr, addrlen) < 0) {
    warn ("resolver::udpsock: connect: %m\n");
    close (fd);
    return false;
  }
  udpsock = New refcounted<dnssock_udp> (fd, wrap (this, &resolver::pktready,
						   false));
  return true;
}
Beispiel #14
0
// Listen for connections
void
net::tcp_listen(int port, cbsb cb)
{
  int ret;
  int tmp_socket;

  // Init socket bound to port
  tmp_socket = inetsocket(SOCK_STREAM, port);
  check_ret(tmp_socket, "inetsocket()");
  
  // Make fd asynchronous
  make_async(tmp_socket);
  
  // Listen for a connection
  ret = listen(tmp_socket, LISTEN_BACKLOG);
  check_ret(ret, "listen()");

  // Schedule event to accept incoming connection 
  fdcb(tmp_socket, selread, wrap(this, &net::tcp_accept, tmp_socket, cb));
}
Beispiel #15
0
int
chanfd::newfd (int rfd, bool _enablercb)
{
  size_t i;
  for (i = 0; i < fdi.size (); i++)
    if (fdi[i].fd == -1 && fdi[i].closed && !fdi[i].rsize)
      break;
  if (i == fdi.size ())
    fdi.push_back ();
      
  fdi[i].reset ();
  fdi[i].fd = rfd;

  fdi[i].isunixsocket = isunixsocket (rfd);

  if (_enablercb)
    enablercb (i);

  make_async (fdi[i].fd);

  return i;
}
Beispiel #16
0
void 
mtdispatch_t::init ()
{

  init_rpc_stats ();

  int fds[2];

  if (num == 0) {
    warn << "Cannot start program with 0 threads; exiting...\n";
    exit (3);
  }

  if (pipe (fds) < 0)
    fatal << "mtdispatch::init: cannot open pipe\n";
  fdin = fds[0];
  make_async (fdin);
  fdcb (fdin, selread, wrap (this, &mtdispatch_t::chld_msg));
  for (u_int i = 0; i < num; i++) {
    launch (i, fds[1]);
  }
  //close (fds[1]);
}
Beispiel #17
0
axprt_dgram::axprt_dgram (int f, bool c, size_t ss, size_t ps)
  : axprt (false, c, c ? 0 : ss), pktsize (ps), fd (f), cb (NULL)
{
  make_async (fd);
  close_on_exec (fd);

#ifdef SO_RCVBUF
  int n = 0;
  socklen_t sn = sizeof (n);
  if (getsockopt (fd, SOL_SOCKET, SO_RCVBUF, &n, &sn) >= 0
      && pktsize > implicit_cast<size_t> (n)) {
    n = pktsize;
    if (setsockopt (fd, SOL_SOCKET, SO_RCVBUF, &n, sizeof (n)) < 0)
      warn ("SO_RCVBUF -> %d bytes: %m\n", n);
  }
#endif /* SO_RCVBUF */

  if (c)
    sabuf = NULL;
  else
    sabuf = (sockaddr *) xmalloc (socksize);
  pktbuf = (char *) xmalloc (pktsize);
}
Beispiel #18
0
// Make a new TCP connection (this blocks)
void
net::tcp_connect(str host, int port) 
{
	int ret;
  int flag;
  struct sockaddr_in sin;

	// Get socket
	fd_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	check_ret(fd_, "socket()");

  // Disable Nagle buffering algorithm
  tcp_nodelay(fd_);

	// Zero structure
	memset(&sin, 0, sizeof(sin));

	// Set to IPV4
	sin.sin_family = AF_INET;
	
	// Convert address
	ret = inet_pton(AF_INET, host.cstr(), &sin.sin_addr.s_addr);
	check_ret(ret, "inet_pton()");

	// Set port
	sin.sin_port = htons(port);
	
	// Establish connection to the server
	ret = connect(fd_, (struct sockaddr*) &sin, sizeof(sin));
	check_ret(ret, "connect()");	

  // Make fd asynchronous
  make_async(fd_); 

	// We are done
}
 listener (int f) : fd (f) {
   make_async (fd);
   close_on_exec (fd);
   listen (fd, 5);
   fdcb (fd, selread, wrap (newserv, fd));
 }
Beispiel #20
0
noise_from_fd::noise_from_fd (datasink *dst, int fd, cbv cb, size_t maxbytes)
  : dst (dst), fd (fd), bytes (maxbytes), cb (cb)
{
  make_async (fd);
  fdcb (fd, selread, wrap (this, &noise_from_fd::doread));
}