Ejemplo n.º 1
0
void
sfssrv_proxy::mkproxy (ref<bool> dest, int cfd, str data, svccb *sbp, int sfd)
{
    if (*dest) {
        sbp->replyref (sfs_connectres (SFS_TEMPERR));
        close (cfd);
        close (sfd);
        return;
    }
    if (sfd < 0) {
        warn << host << ":" << port << ": " << strerror (errno) << "\n";
        sbp->replyref (sfs_connectres (SFS_TEMPERR));
        close (cfd);
        return;
    }
    sbp->ignore ();
    proxy *pp = New proxy (cfd, sfd);
    proxies.insert_head (pp);
    suio_print (&pp->con[1].wbuf, data);
    pp->setcb (1);
}
void
sfssrv_unix::clone (ref<axprt_clone> xc, svccb *sbp)
{
  if (!x || x->ateof ()) {
    launch ();
    if (!x || x->ateof ()) {
      sbp->replyref (sfs_connectres (SFS_TEMPERR));
      return;
    }
  }
  sbp->ignore ();
  x->clone (xc);
}
static void
sclone (ref<asrv> s, ref<axprt_clone> x, sockaddr_in sin, svccb *sbp)
{
  s->setcb (NULL);
  if (!sbp) {
    warn ("invalid connect from %s\n", inet_ntoa (sin.sin_addr));
    return;
  }
  if (sbp->proc () != SFSPROC_CONNECT) {
    sbp->reject (PROC_UNAVAIL);
    return;
  }

  sfs_connectarg *arg = sbp->Xtmpl getarg<sfs_connectarg> ();
  u_int32_t rel;
  sfs_service service;
  str name;
  sfs_hash hostid;
  rpc_vec<sfs_extension, RPC_INFINITY> *extensions;

  switch (arg->civers) {
  case 4:
    rel = 4;
    service = arg->ci4->service;
    name = arg->ci4->name;
    hostid = arg->ci4->hostid;
    extensions = &arg->ci4->extensions;
    break;
  case 5:
    rel = arg->ci5->release;
    service = arg->ci5->service;
    if (!sfs_parsepath (arg->ci5->sname, &name, &hostid))
      name = arg->ci5->sname;
    extensions = &arg->ci5->extensions;
    break;
  default:
    sbp->reject (GARBAGE_ARGS);
    return;
  }

  bhash<str> eh;
  for (const sfs_extension *ep = extensions->base ();
       ep < extensions->lim (); ep++)
    eh.insert (*ep);

  sfs_pathrevoke cert;
  str rawcert = file2str (revocationdir << "/" << 
			  armor32 (hostid.base (), hostid.size ()));
  if (rawcert && str2xdr (cert, rawcert)) {
    sfs_connectres res(SFS_REDIRECT);
    res.revoke->msg = cert.msg;
    res.revoke->sig = cert.sig;
    sbp->reply (&res);
    return;
  }

  const char *source = inet_ntoa (sin.sin_addr);

  server *srv;
  for (srv = serverlist.first; srv; srv = serverlist.next (srv))
    if (srv->host == name && srv->hostid && *srv->hostid == hostid)
      if (srv->clone (x, sbp, source, rel, service, eh))
	return;
      else
	break;
  for (srv = serverlist.first; srv; srv = serverlist.next (srv))
    if (srv->host == name && !srv->hostid)
      if (srv->clone (x, sbp, source, rel, service, eh))
	return;
      else
	break;
  for (srv = serverlist.first; srv; srv = serverlist.next (srv))
    if (srv->host == name)
      if (srv->clone (x, sbp, source, rel, service, eh))
	return;
  for (srv = serverlist.first; srv; srv = serverlist.next (srv))
    if (srv->clone (x, sbp, source, rel, service, eh))
      return;
  sbp->replyref (sfs_connectres (SFS_NOSUCHHOST));
}