Ejemplo n.º 1
0
static void
checkTimeouts(void)
{
    int fd;
    fde *F = NULL;
    PF *callback;
    for (fd = 0; fd <= Biggest_FD; fd++) {
	F = &fd_table[fd];
	if (!F->flags.open)
	    continue;
	if (F->flags.backoff) {
	    switch (commDeferRead(fd)) {
	    case 0:
		commResumeFD(fd);
		break;
#if DELAY_POOLS
	    case -1:
		commAddSlow(fd);
		break;
#endif
	    }
	}
	if (F->timeout == 0)
	    continue;
	if (F->timeout > squid_curtime)
	    continue;
	debug(5, 5) ("checkTimeouts: FD %d Expired\n", fd);
	if (F->flags.backoff)
	    commResumeFD(fd);
	if (F->timeout_handler) {
	    debug(5, 5) ("checkTimeouts: FD %d: Call timeout handler\n", fd);
	    callback = F->timeout_handler;
	    F->timeout_handler = NULL;
	    callback(fd, F->timeout_data);
	} else {
	    debug(5, 5) ("checkTimeouts: FD %d: Forcing comm_close()\n", fd);
	    comm_close(fd);
	}
    }
}
Ejemplo n.º 2
0
/* This will be called when data is ready to be read from fd.  Read until
 * error or connection closed. */
static void
waisReadReply(int fd, void *data)
{
    WaisStateData *waisState = data;
    LOCAL_ARRAY(char, buf, 4096);
    StoreEntry *entry = waisState->entry;
    int len;
    int clen;
    int bin;
    size_t read_sz;
#if DELAY_POOLS
    delay_id delay_id = delayMostBytesAllowed(entry->mem_obj);
#endif
    if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
	comm_close(fd);
	return;
    }
    errno = 0;
    read_sz = 4096;
#if DELAY_POOLS
    read_sz = delayBytesWanted(delay_id, 1, read_sz);
#endif
    Counter.syscalls.sock.reads++;
    len = read(fd, buf, read_sz);
    if (len > 0) {
	fd_bytes(fd, len, FD_READ);
#if DELAY_POOLS
	delayBytesIn(delay_id, len);
#endif
	kb_incr(&Counter.server.all.kbytes_in, len);
	kb_incr(&Counter.server.other.kbytes_in, len);
    }
    debug(24, 5) ("waisReadReply: FD %d read len:%d\n", fd, len);
    if (len > 0) {
	commSetTimeout(fd, Config.Timeout.read, NULL, NULL);
	IOStats.Wais.reads++;
	for (clen = len - 1, bin = 0; clen; bin++)
	    clen >>= 1;
	IOStats.Wais.read_hist[bin]++;
    }
Ejemplo n.º 3
0
static void
helperStatefulServerFree(int fd, void *data)
{
    helper_stateful_server *srv = data;
    statefulhelper *hlp = srv->parent;
    helper_stateful_request *r;
    assert(srv->rfd == fd);
    if (srv->buf) {
	memFree(srv->buf, MEM_8K_BUF);
	srv->buf = NULL;
    }
    if ((r = srv->request)) {
	if (cbdataValid(r->data))
	    r->callback(r->data, srv, srv->buf);
	helperStatefulRequestFree(r);
	srv->request = NULL;
    }
    /* TODO: walk the local queue of requests and carry them all out */
    if (srv->wfd != srv->rfd && srv->wfd != -1)
	comm_close(srv->wfd);
    dlinkDelete(&srv->link, &hlp->servers);
    hlp->n_running--;
    assert(hlp->n_running >= 0);
    if (!srv->flags.shutdown) {
	debug(84, 0) ("WARNING: %s #%d (FD %d) exited\n",
	    hlp->id_name, srv->index + 1, fd);
	if (hlp->n_running <= hlp->n_to_start / 2) {
	    debug(80, 0) ("Too few %s processes are running", hlp->id_name);
	    if (hlp->last_restart > squid_curtime - 30)
		fatalf("The %s helpers are crashing too rapidly, need help!\n", hlp->id_name);
	    debug(80, 0) ("Starting new helpers\n");
	    helperStatefulOpenServers(hlp);
	}
    }
    if (srv->data != NULL)
	memPoolFree(hlp->datapool, srv->data);
    cbdataUnlock(srv->parent);
    cbdataFree(srv);
}
Ejemplo n.º 4
0
void on_clear_button_clicked(GtkObject *object, gpointer user_data)
{
	int32_t error_code = ERR_NONE;

	if (0 > comm_init(com_port_name))
		error_code = ERR_PORT_INIT;

	if (ERR_NONE == error_code)
		error_code = send_password("WIFIBOT123");

	if (ERR_NONE == error_code)
		error_code = clear_lcd();

	if (ERR_NONE == error_code)
	{
		draw_lcd(wm->lcd_text, "");
	}

	comm_close();

	error_handler(wm->window, error_code);
}
Ejemplo n.º 5
0
static void
icapReadReply3(IcapStateData * icap)
{
    StoreEntry *entry = icap->respmod.entry;
    int fd = icap->icap_fd;
    debug(81, 3) ("icapReadReply3\n");
    if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
	debug(81, 3) ("icapReadReply3: Entry Aborded\n");
	comm_close(fd);
    } else if (icapPconnTransferDone(fd, icap)) {
	storeComplete(entry);
	icapRespModKeepAliveOrClose(icap);
    } else if (!icap->flags.no_content) {
	/* Wait for EOF condition */
	commSetSelect(fd, COMM_SELECT_READ, icapReadReply, icap, 0);
	debug(81,
	    3)
	    ("icapReadReply3: Going to read mode data throught icapReadReply\n");
    } else {
	debug(81, 3) ("icapReadReply3: Nothing\n");
    }
}
Ejemplo n.º 6
0
/*
 * icapRespModKeepAliveOrClose
 *
 * Called when we are done reading from the ICAP server.
 * Either close the connection or keep it open for a future
 * transaction.
 */
static void
icapRespModKeepAliveOrClose(IcapStateData * icap)
{
    int fd = icap->icap_fd;
    if (fd < 0)
	return;
    if (!icap->flags.keep_alive) {
	debug(81, 3) ("%s:%d keep_alive not set, closing\n", __FILE__,
	    __LINE__);
	comm_close(fd);
	return;
    }
    debug(81, 3) ("%s:%d FD %d looks good, keeping alive\n", __FILE__, __LINE__,
	fd);
    commSetDefer(fd, NULL, NULL);
    commSetTimeout(fd, -1, NULL, NULL);
    commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
    comm_remove_close_handler(fd, icapStateFree, icap);
    pconnPush(fd, icap->current_service->hostname, icap->current_service->port);
    icap->icap_fd = -1;
    icapStateFree(-1, icap);
}
Ejemplo n.º 7
0
/* Writes data from the server buffer to the client side */
static void
sslWriteClient(int fd, void *data)
{
    SslStateData *sslState = data;
    int len;
    assert(fd == sslState->client.fd);
    debug(26, 3) ("sslWriteClient: FD %d, %d bytes to write\n",
	fd, sslState->server.len);
    Counter.syscalls.sock.writes++;
    len = write(fd,
	sslState->server.buf,
	sslState->server.len);
    debug(26, 3) ("sslWriteClient: FD %d, %d bytes written\n", fd, len);
    if (len > 0) {
	fd_bytes(fd, len, FD_WRITE);
	kb_incr(&Counter.client_http.kbytes_out, len);
	assert(len <= sslState->server.len);
	sslState->server.len -= len;
	/* increment total object size */
	if (sslState->size_ptr)
	    *sslState->size_ptr += len;
	if (sslState->server.len > 0) {
	    /* we didn't write the whole thing */
	    xmemmove(sslState->server.buf,
		sslState->server.buf + len,
		sslState->server.len);
	}
    }
    cbdataLock(sslState);
    if (len < 0) {
	debug(50, ignoreErrno(errno) ? 3 : 1)
	    ("sslWriteClient: FD %d: write failure: %s.\n", fd, xstrerror());
	if (!ignoreErrno(errno))
	    comm_close(fd);
    }
    if (cbdataValid(sslState))
	sslSetSelect(sslState);
    cbdataUnlock(sslState);
}
Ejemplo n.º 8
0
static void
private_fwdInitiateSSL(int fd,server *s)
{
	SSL *ssl;
	SSL_CTX *sslContext = NULL;

	sslContext = Config.ssl_client.sslContext;
	assert(sslContext);
	if ((ssl = SSL_new(sslContext)) == NULL)
	{
		debug(153, 1) ("private_fwdInitiateSSL: Error allocating handle: %s\n",ERR_error_string(ERR_get_error(), NULL));
		cbdataFree(s);
		comm_close(fd);
		return ;
	}
	SSL_set_fd(ssl, fd);
	fd_table[fd].ssl = ssl;
	fd_table[fd].read_method = &ssl_read_method;
	fd_table[fd].write_method = &ssl_write_method;
	fd_note(fd, "private_Negotiating SSL");
    private_fwdNegotiateSSL(fd,s);
	return;
}
Ejemplo n.º 9
0
void
helperStatefulShutdown(statefulhelper * hlp)
{
    dlink_node *link = hlp->servers.head;
    helper_stateful_server *srv;
    int wfd;
    while (link) {
	srv = link->data;
	link = link->next;
	if (!srv->flags.alive) {
	    debug(84, 3) ("helperStatefulShutdown: %s #%d is NOT ALIVE.\n",
		hlp->id_name, srv->index + 1);
	    continue;
	}
	srv->flags.shutdown = 1;	/* request it to shut itself down */
	if (srv->flags.busy) {
	    debug(84, 3) ("helperStatefulShutdown: %s #%d is BUSY.\n",
		hlp->id_name, srv->index + 1);
	    continue;
	}
	if (srv->flags.closing) {
	    debug(84, 3) ("helperStatefulShutdown: %s #%d is CLOSING.\n",
		hlp->id_name, srv->index + 1);
	    continue;
	}
	if (srv->flags.reserved) {
	    debug(84, 3) ("helperStatefulShutdown: %s #%d is RESERVED.\n",
		hlp->id_name, srv->index + 1);
	    continue;
	}
	srv->flags.closing = 1;
	wfd = srv->wfd;
	srv->wfd = -1;
	comm_close(wfd);
    }
}
Ejemplo n.º 10
0
int
ipcCreate(int type, const char *prog, char *const args[], const char *name, int *rfd, int *wfd)
{
    pid_t pid;
    struct sockaddr_in CS;
    struct sockaddr_in PS;
    int crfd = -1;
    int prfd = -1;
    int cwfd = -1;
    int pwfd = -1;
    int fd;
    int t1, t2, t3;
    socklen_t len;
    int tmp_s;
#if HAVE_PUTENV
    char *env_str;
#endif
    int x;

#if HAVE_POLL && defined(_SQUID_OSF_)
    assert(type != IPC_FIFO);
#endif

    if (rfd)
	*rfd = -1;
    if (wfd)
	*wfd = -1;
    if (type == IPC_TCP_SOCKET) {
	crfd = cwfd = comm_open(SOCK_STREAM,
	    0,
	    local_addr,
	    0,
	    COMM_NOCLOEXEC,
	    name);
	prfd = pwfd = comm_open(SOCK_STREAM,
	    0,			/* protocol */
	    local_addr,
	    0,			/* port */
	    0,			/* blocking */
	    name);
    } else if (type == IPC_UDP_SOCKET) {
	crfd = cwfd = comm_open(SOCK_DGRAM,
	    0,
	    local_addr,
	    0,
	    COMM_NOCLOEXEC,
	    name);
	prfd = pwfd = comm_open(SOCK_DGRAM,
	    0,
	    local_addr,
	    0,
	    0,
	    name);
    } else if (type == IPC_FIFO) {
	int p2c[2];
	int c2p[2];
	if (pipe(p2c) < 0) {
	    debug(50, 0) ("ipcCreate: pipe: %s\n", xstrerror());
	    return -1;
	}
	if (pipe(c2p) < 0) {
	    debug(50, 0) ("ipcCreate: pipe: %s\n", xstrerror());
	    return -1;
	}
	fd_open(prfd = p2c[0], FD_PIPE, "IPC FIFO Parent Read");
	fd_open(cwfd = p2c[1], FD_PIPE, "IPC FIFO Child Write");
	fd_open(crfd = c2p[0], FD_PIPE, "IPC FIFO Child Read");
	fd_open(pwfd = c2p[1], FD_PIPE, "IPC FIFO Parent Write");
    } else {
	assert(IPC_NONE);
    }
    debug(54, 3) ("ipcCreate: prfd FD %d\n", prfd);
    debug(54, 3) ("ipcCreate: pwfd FD %d\n", pwfd);
    debug(54, 3) ("ipcCreate: crfd FD %d\n", crfd);
    debug(54, 3) ("ipcCreate: cwfd FD %d\n", cwfd);

    if (crfd < 0) {
	debug(54, 0) ("ipcCreate: Failed to create child FD.\n");
	return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
    }
    if (pwfd < 0) {
	debug(54, 0) ("ipcCreate: Failed to create server FD.\n");
	return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
    }
    if (type == IPC_TCP_SOCKET || type == IPC_UDP_SOCKET) {
	len = sizeof(PS);
	memset(&PS, '\0', len);
	if (getsockname(pwfd, (struct sockaddr *) &PS, &len) < 0) {
	    debug(50, 0) ("ipcCreate: getsockname: %s\n", xstrerror());
	    return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
	}
	debug(54, 3) ("ipcCreate: FD %d sockaddr %s:%d\n",
	    pwfd, inet_ntoa(PS.sin_addr), ntohs(PS.sin_port));
	len = sizeof(CS);
	memset(&CS, '\0', len);
	if (getsockname(crfd, (struct sockaddr *) &CS, &len) < 0) {
	    debug(50, 0) ("ipcCreate: getsockname: %s\n", xstrerror());
	    return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
	}
	debug(54, 3) ("ipcCreate: FD %d sockaddr %s:%d\n",
	    crfd, inet_ntoa(CS.sin_addr), ntohs(CS.sin_port));
    }
    if (type == IPC_TCP_SOCKET) {
	if (listen(crfd, 1) < 0) {
	    debug(50, 1) ("ipcCreate: listen FD %d: %s\n", crfd, xstrerror());
	    return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
	}
	debug(54, 3) ("ipcCreate: FD %d listening...\n", crfd);
    }
    /* flush or else we get dup data if unbuffered_logs is set */
    logsFlush();
    if ((pid = fork()) < 0) {
	debug(50, 1) ("ipcCreate: fork: %s\n", xstrerror());
	return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
    }
    if (pid > 0) {		/* parent */
	/* close shared socket with child */
	comm_close(crfd);
	if (cwfd != crfd)
	    comm_close(cwfd);
	cwfd = crfd = -1;
	if (type == IPC_TCP_SOCKET || type == IPC_UDP_SOCKET) {
	    if (comm_connect_addr(pwfd, &CS) == COMM_ERROR)
		return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
	}
	memset(hello_buf, '\0', HELLO_BUF_SZ);
	if (type == IPC_UDP_SOCKET)
	    x = recv(prfd, hello_buf, HELLO_BUF_SZ - 1, 0);
	else
	    x = read(prfd, hello_buf, HELLO_BUF_SZ - 1);
	if (x < 0) {
	    debug(50, 0) ("ipcCreate: PARENT: hello read test failed\n");
	    debug(50, 0) ("--> read: %s\n", xstrerror());
	    return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
	} else if (strcmp(hello_buf, hello_string)) {
	    debug(54, 0) ("ipcCreate: PARENT: hello read test failed\n");
	    debug(54, 0) ("--> read returned %d\n", x);
	    debug(54, 0) ("--> got '%s'\n", rfc1738_escape(hello_buf));
	    return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
	}
	commSetTimeout(prfd, -1, NULL, NULL);
	commSetNonBlocking(prfd);
	commSetNonBlocking(pwfd);
	if (rfd)
	    *rfd = prfd;
	if (wfd)
	    *wfd = pwfd;
	fd_table[prfd].flags.ipc = 1;
	fd_table[pwfd].flags.ipc = 1;
	return pwfd;
    }
    /* child */
    no_suid();			/* give up extra priviliges */
    /* close shared socket with parent */
    close(prfd);
    if (pwfd != prfd)
	close(pwfd);
    pwfd = prfd = -1;

    if (type == IPC_TCP_SOCKET) {
	debug(54, 3) ("ipcCreate: calling accept on FD %d\n", crfd);
	if ((fd = accept(crfd, NULL, NULL)) < 0) {
	    debug(50, 0) ("ipcCreate: FD %d accept: %s\n", crfd, xstrerror());
	    _exit(1);
	}
	debug(54, 3) ("ipcCreate: CHILD accepted new FD %d\n", fd);
	close(crfd);
	cwfd = crfd = fd;
    } else if (type == IPC_UDP_SOCKET) {
	if (comm_connect_addr(crfd, &PS) == COMM_ERROR)
	    return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
    }
    if (type == IPC_UDP_SOCKET) {
	x = send(cwfd, hello_string, strlen(hello_string), 0);
	if (x < 0) {
	    debug(50, 0) ("sendto FD %d: %s\n", cwfd, xstrerror());
	    debug(50, 0) ("ipcCreate: CHILD: hello write test failed\n");
	    _exit(1);
	}
    } else {
	if (write(cwfd, hello_string, strlen(hello_string)) < 0) {
	    debug(50, 0) ("write FD %d: %s\n", cwfd, xstrerror());
	    debug(50, 0) ("ipcCreate: CHILD: hello write test failed\n");
	    _exit(1);
	}
    }
#if HAVE_PUTENV
    env_str = xcalloc((tmp_s = strlen(Config.debugOptions) + 32), 1);
    snprintf(env_str, tmp_s, "SQUID_DEBUG=%s", Config.debugOptions);
    putenv(env_str);
#endif
    /*
     * This double-dup stuff avoids problems when one of 
     *  crfd, cwfd, or debug_log are in the rage 0-2.
     */
    do {
	x = open(_PATH_DEVNULL, 0, 0444);
	if (x > -1)
	    commSetCloseOnExec(x);
    } while (x < 3);
    t1 = dup(crfd);
    t2 = dup(cwfd);
    t3 = dup(fileno(debug_log));
    assert(t1 > 2 && t2 > 2 && t3 > 2);
    close(crfd);
    close(cwfd);
    close(fileno(debug_log));
    dup2(t1, 0);
    dup2(t2, 1);
    dup2(t3, 2);
    close(t1);
    close(t2);
    close(t3);
#if HAVE_SETSID
    setsid();
#endif
    execvp(prog, args);
    debug(50, 0) ("ipcCreate: %s: %s\n", prog, xstrerror());
    _exit(1);
    return 0;
}
Ejemplo n.º 11
0
void *comm_server_loop(

  comm_thread_t *thread) 

  {
  int sd;

  struct sockaddr_in sa;

  char buffer[BUFSIZ];
  struct sockaddr_in ca;
  int cl = sizeof(ca);
  fd_set rset, allset;
  int wakeup_fd = thread->wakeup_fdr;
  int maxfd;
  int i;

  if (thread == NULL)
    {
    /* FAILURE */

    return;
    }

  /* NOTE:  previously initialized w/
       struct sockaddr_in sa = {AF_INET,htons(thread->port),{INADDR_ANY},""}; */

  sa.sin_family = AF_INET;
  sa.sin_port = htons(thread->port);
  sa.sin_addr.s_addr = htonl(INADDR_ANY);
  sa.sin_zero[0] = '\0';

  sd = socket(AF_INET,SOCK_STREAM,0);

  if (sd < 0) 
    {
    thread->error_handler(strerror(errno));

    return(NULL);
    }

  if (bind(sd,(struct sockaddr*)&sa,sizeof(sa)) < 0) 
    {
    thread->error_handler("unable to bind to port %d (%s)",
      thread->port,
      strerror(errno));

    return(NULL);
    }

  if (listen(sd,16) < 0) 
    {
    thread->error_handler(strerror(errno));

    return(NULL);
    }

  FD_ZERO(&allset);
  FD_SET(sd,&allset);
  FD_SET(wakeup_fd,&allset);

  maxfd = (sd > wakeup_fd) ? sd : wakeup_fd;

  for (;;) 
    {
    rset = allset;

    if (select(maxfd + 1,&rset,NULL,NULL,NULL) < 0) 
      {
      thread->error_handler(strerror(errno));

      return(NULL);
      }

    if (FD_ISSET(wakeup_fd,&rset)) 
      {
      int action = 0;

      if (read(wakeup_fd,&action,sizeof(int)) != sizeof(int)) 
        {
        thread->error_handler(strerror(errno));

        return(NULL);
        }

      if (action == 0) /* stop */
        {
        return(NULL);
        }
      else if (action > 0) /* open */
        {
        FD_SET(action,&allset);
        }
      else /* close */
        {
        FD_CLR(action,&allset);
        }
      }    /* END if (FD_ISSET(wakeup_fd,&rset)) */

    if (FD_ISSET(sd,&rset)) 
      {
      int cd;

      communication_t *comm;

      cd = accept(sd,(struct sockaddr*)&ca,(socklen_t *)&cl);

      if (cd < 0) 
        {
        thread->error_handler(strerror(errno));

        continue;
        }

      if (cl != sizeof(ca)) 
        {
        close(cd);

        thread->error_handler("unknown sockaddr type");

        continue;
        }

      comm = communication_new(thread);

      comm->fd = cd;

      if (comm_thread_add_connection(thread,comm) < 0)
        {
        communication_free(comm);

        continue;
        }

      if (thread->open_handler(comm)) 
        {
        thread->connections--;

        communication_free(comm);

        continue;
        }

      FD_SET(cd,&allset);

      if (cd > maxfd)
        maxfd = cd;

      continue;
      }  /* END if (FD_ISSET(sd,&rset)) */

    for (i = 0;i < thread->connections;i++) 
      {
      communication_t* comm = thread->connection[i];

      if (comm->fd > 0 && FD_ISSET(comm->fd,&rset)) 
        {
        int n;

        n = read(comm->fd,buffer,BUFSIZ);

        if (n < 0) 
          {
          thread->error_handler(strerror(errno));
          }
        else if (n == 0) 
          {
          thread->close_handler(comm);

          FD_CLR(comm->fd,&allset);

          comm_close(comm);
          }
        else if (thread->read_handler(comm,buffer,n)) 
          {
          FD_CLR(comm->fd,&allset);

          comm_close(comm);
          }
        }
      }
    }    /* END for (i) */

  close(sd);

  return(0);
  }  /* END comm_server_loop() */
Ejemplo n.º 12
0
void* comm_client_loop(

  comm_thread_t *thread) 
 
  {
  char buffer[BUFSIZ];
  fd_set allrset;
  fd_set allwset;
  fd_set wset;
  fd_set rset;
  int i;
  int wakeup_fd = thread->wakeup_fdr;
  int maxfd = wakeup_fd;

  FD_ZERO(&allrset);
  FD_ZERO(&allwset);
  FD_SET(wakeup_fd, &allrset);

  for (;;) 
    {
    int close_fd = -1;

    rset = allrset;
    wset = allwset;

    if (select(maxfd + 1,&rset,&wset,NULL,NULL) < 0) 
      {
      thread->error_handler("select failed: %s", 
        strerror(errno));

      return(NULL);
      }

    if (FD_ISSET(wakeup_fd,&rset)) 
      {
      int action = 0;

      if (read(wakeup_fd,&action,sizeof(int)) != sizeof(int)) 
        {
        thread->error_handler("pipe read failed: %s",  
          strerror(errno));

        return(NULL);
        }

      if (action == 0) 
        { 
        /* stop */

        thread->error_handler("communication thread stopped");

        return(NULL);
        }

      if (action > 0) 
        { 
        /* open */

        FD_SET(action,&allrset);
        FD_SET(action,&allwset);

        if (action > maxfd)
          maxfd = action;
        }
      else 
        { 
        /* close */

        action = -action;

        FD_CLR(action,&allrset);
        FD_CLR(action,&allwset);

        close_fd = action;
        }
      }    /* END if (FD_ISSET(wakeup_fd,&rset)) */

    for (i = 0;i < thread->connections;i++) 
      {
      communication_t *comm = thread->connection[i];

      int fd;

      fd = comm->fd;

      if (fd < 0)
        continue;

      if (FD_ISSET(fd,&wset)) 
        {
        int error;
        int errsiz = sizeof(int);

        FD_CLR(fd,&allwset);

        if (getsockopt(fd,SOL_SOCKET,SO_ERROR,&error,(socklen_t *)&errsiz) < 0) 
          {
          thread->error_handler(strerror(errno));

          comm_close(comm);

          continue;
          }

        if (error != 0) 
          {
          thread->error_handler(strerror(error));
 
          comm_close(comm);

          continue;
          }

        thread->open_handler(comm);
        }

      if (FD_ISSET(fd,&rset)) 
        {
        int n = read(fd,buffer,BUFSIZ);

        if (n < 0) 
          {
          thread->error_handler(strerror(errno));
          }
        else if (n == 0) 
          {
          thread->close_handler(comm);

          FD_CLR(fd, &allrset);

          comm_close(comm);
          }
        else if (thread->read_handler(comm,buffer,n)) 
          {
          FD_CLR(fd,&allrset);

          comm_close(comm);
          }
        }
      }    /* END for (i) */   

    if ((close_fd > 0) && (close(close_fd) < 0))
      thread->error_handler(strerror(errno));
    }  /* END for (;;) */

  return(NULL);
  }  /* END comm_client_loop() */
Ejemplo n.º 13
0
static void
icapSendRespModDone(int fd, char *bufnotused, size_t size, int errflag,
    void *data)
{
    IcapStateData *icap = data;
    ErrorState *err;

    icap->flags.write_pending = 0;
    debug(81, 5) ("icapSendRespModDone: FD %d: size %d: errflag %d.\n",
	fd, size, errflag);
    if (size > 0) {
	fd_bytes(fd, size, FD_WRITE);
	kb_incr(&statCounter.icap.all.kbytes_out, size);
    }
    if (errflag == COMM_ERR_CLOSING)
	return;
    if (errflag) {
	err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
	err->xerrno = errno;
	if (cbdataValid(icap))
	    err->request = requestLink(icap->request);
	storeEntryReset(icap->respmod.entry);
	errorAppendEntry(icap->respmod.entry, err);
	comm_close(fd);
	return;
    }
    if (EBIT_TEST(icap->respmod.entry->flags, ENTRY_ABORTED)) {
        debug(81, 3) ("icapSendRespModDone: Entry Aborded\n");	
	comm_close(fd);
	return;
    }
    if (icap->flags.send_zero_chunk) {
	debug(81,
	    3) ("icapSendRespModDone: I'm supposed to send zero chunk now\n");
	icap->flags.send_zero_chunk = 0;
	icapSendRespMod(icap, NULL, 0, 1);
	return;
    }
    if (icap->flags.wait_for_preview_reply || icap->flags.wait_for_reply) {
	/* Schedule reading the ICAP response */
	debug(81,
	    3)
	    ("icapSendRespModDone: FD %d: commSetSelect on read icapRespModReadReply.\n",
	    fd);
	commSetSelect(fd, COMM_SELECT_READ, icapRespModReadReply, icap, 0);
#if 1
	commSetTimeout(fd, Config.Timeout.read, icapReadTimeout, icap);
#else
	if (icap->flags.wait_for_preview_reply || icap->flags.http_server_eof) {
	    /*
	     * Set the read timeout only after all data has been sent
	     * or we are waiting for a preview response
	     * If the ICAP server does not return any data till all data
	     * has been sent, we are likely to hit the timeout for large
	     * HTTP bodies
	     */
	    commSetTimeout(fd, Config.Timeout.read, icapReadTimeout, icap);
	}
#endif
    }
}
Ejemplo n.º 14
0
static void clientRecvFd(int sock, void *data)
{
	int retval;     
	struct msghdr msg;
	struct iovec vec;       
	char cmsgbuf[CMSG_SPACE(sizeof(int))];
	struct cmsghdr *p_cmsg;
	char iov_buf[CACHE_WATCH_RECV_MSG_LENGTH];

	vec.iov_base = iov_buf;
	vec.iov_len = CACHE_WATCH_RECV_MSG_LENGTH;
	msg.msg_name = NULL;    
	msg.msg_namelen = 0;
	msg.msg_iov = &vec; 
	msg.msg_iovlen = 1;
	msg.msg_control = cmsgbuf;
	msg.msg_controllen = sizeof(cmsgbuf);   
	msg.msg_flags = 0;      /* In case something goes wrong, set the fd to -1 before the syscall */
	retval = recvmsg(sock, &msg, 0);

	if( retval <= 0 )
	{       
		comm_close(sock);
		return; 
	}       

	if( (p_cmsg = CMSG_FIRSTHDR(&msg)) == NULL )
	{       
		comm_close(sock);
		return; 
	}       

    if (squidWatchReply(sock, &msg, iov_buf) != -1)
    {
        comm_close(sock);
        return;
    }

	int fd = *((int*)CMSG_DATA(p_cmsg));
	// for keep alive
	commSetSelect(sock, COMM_SELECT_READ, clientRecvFd, NULL, 0);
	// omm_close(sock);
	if(fd < 0)
	{
		return;
	}
	//comm_accept's jobs
	struct sockaddr_in peername;
	struct sockaddr_in sockname;
	socklen_t socklen;
	socklen = sizeof(struct sockaddr_in);
	memset(&peername, '\0', socklen);
	memset(&sockname, '\0', socklen);
	getpeername(fd, (struct sockaddr *)&peername, &socklen);
	getsockname(fd, (struct sockaddr *)&sockname, &socklen);
	commSetCloseOnExec(fd);
	fd_open(fd, FD_SOCKET, "HTTP Request");
	fde *F = &fd_table[fd];
	xstrncpy(F->ipaddr, xinet_ntoa(peername.sin_addr), 16);
	F->remote_port = htons(peername.sin_port);
	F->local_port = htons(sockname.sin_port);
	commSetNonBlocking(fd);
	//rest of httpAccept's jobs
    //
    //int on = 1;
    //if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof(on)) < 0)
    //    debug(191, 0) ("commSetTcpNoDelay: FD %d: %s\n", fd, xstrerror());
    //fd_table[fd].flags.nodelay = 1;
#ifdef TCP_NODELAY
	commSetTcpNoDelay(fd); /*Fix tcp use Negale bug while send packet*/
#endif

#ifdef CC_FRAMEWORK
	cc_call_hook_func_private_http_accept(fd);
#endif

	debug(191, 4) ("clientRecvFd: FD %d: accepted port %d client %s:%d\n", fd, F->local_port, F->ipaddr, F->remote_port);
	fd_note_static(fd, "client http connect");
	ConnStateData * connState = cbdataAlloc(ConnStateData);
	assert(Config.Sockaddr.http);
	connState->port = Config.Sockaddr.http;
	cbdataLock(connState->port);
	connState->peer = peername; 
	connState->log_addr = peername.sin_addr;
	connState->log_addr.s_addr &= Config.Addrs.client_netmask.s_addr;
	connState->me = sockname;
	connState->fd = fd;
	connState->pinning.fd = -1;
	connState->in.buf = memAllocBuf(CLIENT_REQ_BUF_SZ, &connState->in.size);
	comm_add_close_handler(fd, connStateFree, connState);
	if (Config.onoff.log_fqdn)
		fqdncache_gethostbyaddr(peername.sin_addr, FQDN_LOOKUP_IF_MISS);
	commSetTimeout(fd, Config.Timeout.request, requestTimeout, connState);
#if USE_IDENT
	static aclCheck_t identChecklist;
	identChecklist.src_addr = peername.sin_addr;
	identChecklist.my_addr = sockname.sin_addr;
	identChecklist.my_port = ntohs(sockname.sin_port);
	if (aclCheckFast(Config.accessList.identLookup, &identChecklist))
		identStart(&sockname, &peername, clientIdentDone, connState);
#endif
	commSetSelect(fd, COMM_SELECT_READ, clientReadRequest, connState, 0);
	commSetDefer(fd, clientReadDefer, connState);
	if (connState->port->tcp_keepalive.enabled)
	{       
		commSetTcpKeepalive(fd, connState->port->tcp_keepalive.idle, connState->port->tcp_keepalive.interval, connState->port->tcp_keepalive.timeout);
	}       

	clientdbEstablished(peername.sin_addr, 1);
	incoming_sockets_accepted++;
}
Ejemplo n.º 15
0
static int
inetport(struct Listener *listener)
{
	int fd;
	int opt = 1;

	/*
	 * At first, open a new socket
	 */

	fd = comm_socket(listener->addr.ss_family, SOCK_STREAM, 0, "Listener socket");

#ifdef IPV6
	if(listener->addr.ss_family == AF_INET6)
	{
		struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &listener->addr;
		if(!IN6_ARE_ADDR_EQUAL(&in6->sin6_addr, &in6addr_any))
		{
			inetntop(AF_INET6, &in6->sin6_addr, listener->vhost,
				 sizeof(listener->vhost));
			listener->name = listener->vhost;
		}
	}
	else
#endif
	{
		struct sockaddr_in *in = (struct sockaddr_in *) &listener->addr;
		if(in->sin_addr.s_addr != INADDR_ANY)
		{
			inetntop(AF_INET, &in->sin_addr, listener->vhost, sizeof(listener->vhost));
			listener->name = listener->vhost;
		}
	}


	if(fd == -1)
	{
		report_error("opening listener socket %s:%s",
			     get_listener_name(listener), get_listener_name(listener), errno);
		return 0;
	}
	else if((maxconnections - 10) < fd)
	{
		report_error("no more connections left for listener %s:%s",
			     get_listener_name(listener), get_listener_name(listener), errno);
		comm_close(fd);
		return 0;
	}
	/*
	 * XXX - we don't want to do all this crap for a listener
	 * set_sock_opts(listener);
	 */
	if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt)))
	{
		report_error("setting SO_REUSEADDR for listener %s:%s",
			     get_listener_name(listener), get_listener_name(listener), errno);
		comm_close(fd);
		return 0;
	}

	/*
	 * Bind a port to listen for new connections if port is non-null,
	 * else assume it is already open and try get something from it.
	 */

	if(bind(fd, (struct sockaddr *) &listener->addr, GET_SS_LEN(listener->addr)))
	{
		report_error("binding listener socket %s:%s",
			     get_listener_name(listener), get_listener_name(listener), errno);
		comm_close(fd);
		return 0;
	}

	if(listen(fd, RATBOX_SOMAXCONN))
	{
		report_error("listen failed for %s:%s",
			     get_listener_name(listener), get_listener_name(listener), errno);
		comm_close(fd);
		return 0;
	}

	listener->fd = fd;

	/* Listen completion events are READ events .. */

	accept_connection(fd, listener);
	return 1;
}
Ejemplo n.º 16
0
/****************************************************************************
 *  Initializing the msxcomm object
 ***************************************************************************/
msx_comm_t*
comm_init( unsigned short *ports, int timeout ){
	int result = 0 ; 
	int i;
	struct sockaddr_in socketInfo ;
      
	msx_comm_t *comm;
      
	/* allocating memory for comm */
	if (!(comm = malloc(sizeof(msx_comm_t))))
		return NULL;

	/* set all the memory to null */ 
	bzero( comm, sizeof(msx_comm_t));
      
	/* timeout of receiving and sending */
	comm->comm_timeout = timeout;
      
	/* Opening, binding and listening on all the external sockets */
	comm->comm_maxfd = -1;

	for(i=0 ; i < COMM_MAX_LISTEN ; i++)
		comm->comm_sock[i] = -1;
	
	for( i = 0 ; i < COMM_MAX_LISTEN ; i++ ) {
		if(ports[i] <= 0){
			/* this socket is not used */
			comm->comm_sock[i] = -1;
			continue;
		}
	  
		/* setup the sock_addr data structure */
		socketInfo.sin_family = PF_INET;
		socketInfo.sin_port = htons( ports[i] );
		socketInfo.sin_addr.s_addr = htonl( INADDR_ANY );
	  
		/* create the new socket */
		if ( ( comm->comm_sock[i] =
		       socket( PF_INET, SOCK_STREAM, 0 ) ) == -1 )	  {
			debug_lr( COMM_DEBUG, "Error: socket()\n" ) ;
			goto exit_with_error;
		}
	    
		/* bind the socket */
		if ( ( result = bind( comm->comm_sock[i],
				      (struct sockaddr *)&socketInfo,
				      sizeof( struct sockaddr ) ) ) == -1 ){
			debug_lr( COMM_DEBUG, "Error: bind()\n" ) ;
			goto exit_with_error;
		}
	    
		if ( ( listen( comm->comm_sock[i], SOMAXCONN ) ) == -1 ){
			debug_lr( COMM_DEBUG, "Error: listen()\n" ) ;
			goto exit_with_error;
		}
	    
		if(comm->comm_sock[i] > comm->comm_maxfd)
			comm->comm_maxfd = comm->comm_sock[i];
	}
      
	/* Initilizing the inprogress socket set */
	comm->comm_inpr_send_next = 0;
	comm->comm_inpr_recv_next = 0;
	comm->comm_close_next = 0;

	/* set the time for the next admin operation */ 
	gettimeofday( &(comm->next_admin), NULL );
	comm->next_admin.tv_sec += COMM_ADMIN_WAIT;
    
	return comm;

 exit_with_error:
	comm_close(comm);
	return NULL;
} 
Ejemplo n.º 17
0
void on_get_button_clicked(GtkObject *object, gpointer wn)
{
	g_print("Get Button Clicked\n");

	int32_t error_code = ERR_NONE;

	if (0 > comm_init(com_port_name))
		error_code = ERR_PORT_INIT;

	if (ERR_NONE == error_code)
		error_code = send_password("WIFIBOT123");

	if (ERR_NONE == error_code)
	{
		uint32_t timestamp;
		error_code = read_current_time(&timestamp);
		if (ERR_NONE == error_code)
			draw_current_time(wm->timestamp_control, timestamp);
	}

	if (ERR_NONE == error_code)
	{
		char program_info[64] = "";
		error_code = read_program_info(program_info);
		if (ERR_NONE == error_code)
			draw_program_info(wm->program_info_control, program_info);
	}

	if (ERR_NONE == error_code)
	{
		int32_t motor_levels[NUMBER_OF_MOTOR_CHANNELS];
		error_code = read_motor_levels(&motor_levels[MOTOR_SPEED_CHANNEL],
				&motor_levels[MOTOR_DIRECTION_CHANNEL]);

		if (ERR_NONE == error_code)
		{
			draw_motor_control(wm->left_motor_slide, wm->left_motor_control,
					motor_levels[MOTOR_SPEED_CHANNEL]);
			draw_motor_control(wm->right_motor_slide, wm->right_motor_control,
					motor_levels[MOTOR_DIRECTION_CHANNEL]);
		}
	}

	if (ERR_NONE == error_code)
	{
		int32_t sensor_levels[NUMBER_OF_SENSOR_CHANNELS];
		error_code = read_sensor_values(&sensor_levels[SENSOR_FWD],
				&sensor_levels[SENSOR_REV]);

		if (ERR_NONE == error_code)
			draw_sensor_values(wm->sensor_value_control, sensor_levels);
	}

	if (ERR_NONE == error_code)
	{
		StatusLedFlashState_t led_state;
		int32_t flash_rate;

		error_code = read_status_led(&led_state, &flash_rate);

		if (ERR_NONE == error_code)
			update_led_control(wm->status_led_control, led_state, flash_rate);
	}

	if (ERR_NONE == error_code)
	{
		int32_t motor_timeout;

		error_code = read_motor_timeout(&motor_timeout);
		if (ERR_NONE == error_code)
			draw_motor_timeout(wm->motor_timeout_control, motor_timeout);
	}

	if (ERR_NONE == error_code)
	{
		bool on;
		error_code = read_ir_led(&on);
		if (ERR_NONE == error_code)
			draw_ir_led(wm->ir_led_control, on);
	}

	if (ERR_NONE == error_code)
	{
		int32_t error_id, error_timestamp;
		error_code = read_last_error(&error_id, &error_timestamp);
		if (ERR_NONE == error_code)
			draw_error_info(wm->error_code, wm->error_timestamp, error_id,
					error_timestamp);
	}

	if (ERR_NONE == error_code)
	{
		bool pressed[NUMBER_OF_PUSHBUTTONS];
		error_code = read_pushbuttons(pressed);
		if (ERR_NONE == error_code)
			draw_pushbuttons(wm->pushbutton, pressed);
	}

	comm_close();

	error_handler(wm->window, error_code);
}
Ejemplo n.º 18
0
static void
accept_connection(int pfd, void *data)
{
	static time_t last_oper_notice = 0;

	struct irc_sockaddr_storage sai;
	socklen_t addrlen = sizeof(sai);
	int fd;
	struct Listener *listener = data;
	struct ConfItem *aconf;
	char buf[BUFSIZE];

	s_assert(listener != NULL);
	if(listener == NULL)
		return;


	for(;;)			/* loop until something breaks us out */
	{

		/*
		 * There may be many reasons for error return, but
		 * in otherwise correctly working environment the
		 * probable cause is running out of file descriptors
		 * (EMFILE, ENFILE or others?). The man pages for
		 * accept don't seem to list these as possible,
		 * although it's obvious that it may happen here.
		 * Thus no specific errors are tested at this
		 * point, just assume that connections cannot
		 * be accepted until some old is closed first.
		 */

		fd = comm_accept(listener->fd, (struct sockaddr *) &sai, &addrlen);

		/* This needs to be done here, otherwise we break dlines */
		mangle_mapped_sockaddr((struct sockaddr *) &sai);

		if(fd < 0)
		{
			/* Re-register a new IO request for the next accept .. */
			comm_setselect(listener->fd, FDLIST_SERVICE,
				       COMM_SELECT_READ, accept_connection, listener);
			return;
		}
		/*
		 * check for connection limit
		 */
		if((maxconnections - 10) < fd)
		{
			++ServerStats->is_ref;
			/*
			 * slow down the whining to opers bit
			 */
			if((last_oper_notice + 20) <= CurrentTime)
			{
				sendto_realops_flags(UMODE_ALL, L_ALL,
						     "All connections in use. (%s)",
						     get_listener_name(listener));
				last_oper_notice = CurrentTime;
			}

			write(fd, "ERROR :All connections in use\r\n", 32);
			comm_close(fd);
			/* Re-register a new IO request for the next accept .. */
			comm_setselect(listener->fd, FDLIST_SERVICE,
				       COMM_SELECT_READ, accept_connection, listener);
			return;
		}

		/* Do an initial check we aren't connecting too fast or with too many
		 * from this IP... */
		if((aconf = conf_connect_allowed((struct sockaddr *) &sai, sai.ss_family)) != NULL)
		{
			ServerStats->is_ref++;

			if(ConfigFileEntry.dline_with_reason)
			{
				if(ircsnprintf
				   (buf, sizeof(buf), "ERROR :*** Banned: %s\r\n",
				    aconf->passwd) >= (sizeof(buf) - 1))
				{
					buf[sizeof(buf) - 3] = '\r';
					buf[sizeof(buf) - 2] = '\n';
					buf[sizeof(buf) - 1] = '\0';
				}
			}
			else
				ircsprintf(buf, "ERROR :You have been D-lined.\r\n");

			write(fd, buf, strlen(buf));
			comm_close(fd);

			/* Re-register a new IO request for the next accept .. */
			comm_setselect(listener->fd, FDLIST_SERVICE,
				       COMM_SELECT_READ, accept_connection, listener);
			return;
		}

		ServerStats->is_ac++;
		add_connection(listener, fd, (struct sockaddr *) &sai);

	}
	/* Re-register a new IO request for the next accept .. */
	comm_setselect(listener->fd, FDLIST_SERVICE, COMM_SELECT_READ,
		       accept_connection, listener);
}
Ejemplo n.º 19
0
static void
icapRespModReadReply(int fd, void *data)
{
    IcapStateData *icap = data;
    int version_major, version_minor;
    const char *str_status;
    int x;
    int status = 0;
    int isIcap = 0;
    int directResponse = 0;
    ErrorState *err;
    const char *start;
    const char *end;

    debug(81, 5) ("icapRespModReadReply: FD %d data = %p\n", fd, data);
    statCounter.syscalls.sock.reads++;

    x = icapReadHeader(fd, icap, &isIcap);
    if (x < 0) {
	/* Did not find a proper ICAP response */
	debug(81, 3) ("ICAP : Error path!\n");
	err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
	err->request = requestLink(icap->request);
	err->xerrno = errno;
	errorAppendEntry(icap->respmod.entry, err);
	comm_close(fd);
	return;
    }
    if (x == 0) {
	/*
	 * Waiting for more headers.  Schedule new read hander, but
	 * don't reset timeout.
	 */
	commSetSelect(fd, COMM_SELECT_READ, icapRespModReadReply, icap, 0);
	return;
    }
    /*
     * Parse the ICAP header
     */
    assert(icap->icap_hdr.size);
    debug(81, 3) ("Parse icap header : <%s>\n", icap->icap_hdr.buf);
    if ((status =
	    icapParseStatusLine(icap->icap_hdr.buf, icap->icap_hdr.size,
		&version_major, &version_minor, &str_status)) < 0) {
	debug(81, 1) ("BAD ICAP status line <%s>\n", icap->icap_hdr.buf);
	/* is this correct in case of ICAP protocol error? */
	err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
	err->request = requestLink(icap->request);
	err->xerrno = errno;
	errorAppendEntry(icap->respmod.entry, err);
	comm_close(fd);
	return;
    };
    /*  OK here we have responce. Lets stop filling the 
     *  icap->respmod.resp_copy buffer ....
     */
    icap->flags.copy_response = 0;

    icapSetKeepAlive(icap, icap->icap_hdr.buf);
#if ICAP_PREVIEW
    if (icap->flags.wait_for_preview_reply) {
	if (100 == status) {
	    debug(81, 5) ("icapRespModReadReply: 100 Continue received\n");
	    icap->flags.wait_for_preview_reply = 0;
	    /* if http_server_eof
	     * call again icapSendRespMod to handle data that
	     * was received while waiting for this ICAP response
	     * else let http to call icapSendRespMod when new data arrived
	     */
	    if (icap->flags.http_server_eof)
		icapSendRespMod(icap, NULL, 0, 0);
	    /*
	     * reset the header to send the rest of the preview
	     */
	    if (!memBufIsNull(&icap->icap_hdr))
		memBufReset(&icap->icap_hdr);

	    /*We do n't need it any more .......*/
	    if (!memBufIsNull(&icap->respmod.resp_copy))
		 memBufClean(&icap->respmod.resp_copy);

	    return;
	}
	if (204 == status) {
	    debug(81,
		5) ("icapRespModReadReply: 204 No modification received\n");
	    icap->flags.wait_for_preview_reply = 0;
	}
    }
#endif /*ICAP_PREVIEW */

#if SUPPORT_ICAP_204 || ICAP_PREVIEW
    if (204 == status) {
	debug(81, 3) ("got 204 status from ICAP server\n");
	debug(81, 3) ("setting icap->flags.no_content\n");
	icap->flags.no_content = 1;
	/*
	 * copy the response already written to the ICAP server
	 */
	debug(81, 3) ("copying %d bytes from resp_copy to chunk_buf\n",
	    icap->respmod.resp_copy.size);
	memBufAppend(&icap->chunk_buf,
	    icap->respmod.resp_copy.buf, icap->respmod.resp_copy.size);
	icap->respmod.resp_copy.size = 0;
	if (icapReadReply2(icap) < 0)
	    comm_close(fd);
	/*
	 * XXX ideally want to clean icap->respmod.resp_copy here
	 * XXX ideally want to "close" ICAP server connection here
	 * OK do it....
	 */
	if (!memBufIsNull(&icap->respmod.resp_copy))
	     memBufClean(&icap->respmod.resp_copy);
	return;
    }
#endif
    if (200 != status) {
	debug(81, 1) ("Unsupported status '%d' from ICAP server\n", status);
	/* Did not find a proper ICAP response */
	err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
	err->request = requestLink(icap->request);
	err->xerrno = errno;
	errorAppendEntry(icap->respmod.entry, err);
	comm_close(fd);
	return;
    }
    if (icapFindHeader(icap->icap_hdr.buf, "Encapsulated:", &start, &end)) {
	icapParseEncapsulated(icap, start, end);
    } else {
	debug(81,
	    1)
	    ("WARNING: icapRespModReadReply() did not find 'Encapsulated' header\n");
    }
    if (icap->enc.res_hdr > -1)
	directResponse = 1;
    else if (icap->enc.res_body > -1)
	directResponse = 1;
    else
	directResponse = 0;

    /*
     * "directResponse" is the normal case here.  If we don't have
     * a response header or body, it is an error.
     */
    if (!directResponse) {
	/* Did not find a proper ICAP response */
	debug(81, 3) ("ICAP : Error path!\n");
	err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
	err->request = requestLink(icap->request);
	err->xerrno = errno;
	errorAppendEntry(icap->respmod.entry, err);
	comm_close(fd);
	return;
    }
    /* got the reply, no need to come here again */
    icap->flags.wait_for_reply = 0;
    icap->flags.got_reply = 1;
    /* Next, gobble any data before the HTTP response starts */
    if (icap->enc.res_hdr > -1)
	icap->bytes_to_gobble = icap->enc.res_hdr;
    commSetSelect(fd, COMM_SELECT_READ, icapRespModGobble, icap, 0);
}
Ejemplo n.º 20
0
static unsigned int __stdcall
ipc_thread_1(void *in_params)
{
    int t1, t2, t3, retval = -1;
    int p2c[2] =
    {-1, -1};
    int c2p[2] =
    {-1, -1};
    HANDLE hProcess = NULL, thread = NULL;
    pid_t pid = -1;
    struct thread_params thread_params;
    int x, tmp_s, fd = -1;
    char *str;
#if HAVE_PUTENV
    char *env_str = NULL;
#endif
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    long F;
    int prfd_ipc = -1, pwfd_ipc = -1, crfd_ipc = -1, cwfd_ipc = -1;
    char *prog = NULL, *buf1 = NULL;
    struct sockaddr_in CS_ipc, PS_ipc;

    struct ipc_params *params = (struct ipc_params *) in_params;
    int type = params->type;
    int crfd = params->crfd;
    int cwfd = params->cwfd;
    char **args = params->args;
    struct sockaddr_in PS = params->PS;


    buf1 = xcalloc(1, 8192);
    strcpy(buf1, params->prog);
    prog = strtok(buf1, w_space);

    if ((str = strrchr(prog, '/')))
	prog = ++str;
    if ((str = strrchr(prog, '\\')))
	prog = ++str;

    prog = xstrdup(prog);

    if (type == IPC_TCP_SOCKET) {
	debug(54, 3) ("ipcCreate: calling accept on FD %d\n", crfd);
	if ((fd = accept(crfd, NULL, NULL)) < 0) {
	    debug(54, 0) ("ipcCreate: FD %d accept: %s\n", crfd, xstrerror());
	    goto cleanup;
	}
	debug(54, 3) ("ipcCreate: CHILD accepted new FD %d\n", fd);
	comm_close(crfd);
	snprintf(buf1, 8191, "%s CHILD socket", prog);
	fd_open(fd, FD_SOCKET, buf1);
	fd_table[fd].flags.ipc = 1;
	cwfd = crfd = fd;
    } else if (type == IPC_UDP_SOCKET) {
	if (comm_connect_addr(crfd, &PS) == COMM_ERROR)
	    goto cleanup;
    }
    x = send(cwfd, hello_string, strlen(hello_string) + 1, 0);

    if (x < 0) {
	debug(54, 0) ("sendto FD %d: %s\n", cwfd, xstrerror());
	debug(54, 0) ("ipcCreate: CHILD: hello write test failed\n");
	goto cleanup;
    }
#if HAVE_PUTENV
    env_str = xcalloc((tmp_s = strlen(Config.debugOptions) + 32), 1);
    snprintf(env_str, tmp_s, "SQUID_DEBUG=%s", Config.debugOptions);
    putenv(env_str);
#endif
    memset(buf1, '\0', sizeof(buf1));
    x = recv(crfd, buf1, 8191, 0);

    if (x < 0) {
	debug(54, 0) ("ipcCreate: CHILD: OK read test failed\n");
	debug(54, 0) ("--> read: %s\n", xstrerror());
	goto cleanup;
    } else if (strcmp(buf1, ok_string)) {
	debug(54, 0) ("ipcCreate: CHILD: OK read test failed\n");
	debug(54, 0) ("--> read returned %d\n", x);
	debug(54, 0) ("--> got '%s'\n", rfc1738_escape(hello_buf));
	goto cleanup;
    }
    /* assign file descriptors to child process */
    if (_pipe(p2c, 1024, _O_BINARY | _O_NOINHERIT) < 0) {
	debug(54, 0) ("ipcCreate: CHILD: pipe: %s\n", xstrerror());
	ipcSend(cwfd, err_string, strlen(err_string));
	goto cleanup;
    }
    if (_pipe(c2p, 1024, _O_BINARY | _O_NOINHERIT) < 0) {
	debug(54, 0) ("ipcCreate: CHILD: pipe: %s\n", xstrerror());
	ipcSend(cwfd, err_string, strlen(err_string));
	goto cleanup;
    }
    if (type == IPC_UDP_SOCKET) {
	snprintf(buf1, 8192, "%s(%ld) <-> ipc CHILD socket", prog, -1L);
	crfd_ipc = cwfd_ipc = comm_open(SOCK_DGRAM, IPPROTO_UDP, local_addr, 0, 0, buf1);

	if (crfd_ipc < 0) {
	    debug(54, 0) ("ipcCreate: CHILD: Failed to create child FD for %s.\n",
		prog);
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	}
	snprintf(buf1, 8192, "%s(%ld) <-> ipc PARENT socket", prog, -1L);
	prfd_ipc = pwfd_ipc = comm_open(SOCK_DGRAM, IPPROTO_UDP, local_addr, 0, 0, buf1);
	if (pwfd_ipc < 0) {
	    debug(54, 0) ("ipcCreate: CHILD: Failed to create server FD for %s.\n",
		prog);
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	}
	tmp_s = sizeof(PS_ipc);
	memset(&PS_ipc, '\0', tmp_s);
	if (getsockname(pwfd_ipc, (struct sockaddr *) &PS_ipc, &tmp_s) < 0) {
	    debug(54, 0) ("ipcCreate: getsockname: %s\n", xstrerror());
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	}
	debug(54, 3) ("ipcCreate: FD %d sockaddr %s:%d\n",
	    pwfd_ipc, inet_ntoa(PS_ipc.sin_addr), ntohs(PS_ipc.sin_port));
	tmp_s = sizeof(CS_ipc);
	memset(&CS_ipc, '\0', tmp_s);
	if (getsockname(crfd_ipc, (struct sockaddr *) &CS_ipc, &tmp_s) < 0) {
	    debug(54, 0) ("ipcCreate: getsockname: %s\n", xstrerror());
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	}
	debug(54, 3) ("ipcCreate: FD %d sockaddr %s:%d\n",
	    crfd_ipc, inet_ntoa(CS_ipc.sin_addr), ntohs(CS_ipc.sin_port));

	if (comm_connect_addr(pwfd_ipc, &CS_ipc) == COMM_ERROR) {
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	}
	fd = crfd;

	if (comm_connect_addr(crfd_ipc, &PS_ipc) == COMM_ERROR) {
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	}
    }				/* IPC_UDP_SOCKET */
    t1 = dup(0);
    t2 = dup(1);
    t3 = dup(2);
    dup2(c2p[0], 0);
    dup2(p2c[1], 1);
    dup2(fileno(debug_log), 2);
    close(c2p[0]);
    close(p2c[1]);

    commUnsetNonBlocking(fd);

    memset(&si, 0, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.hStdInput = (HANDLE) _get_osfhandle(0);
    si.hStdOutput = (HANDLE) _get_osfhandle(1);
    si.hStdError = (HANDLE) _get_osfhandle(2);
    si.dwFlags = STARTF_USESTDHANDLES;

    /* Make sure all other valid handles are not inerithable */
    for (x = 3; x < Squid_MaxFD; x++) {
	if ((F = _get_osfhandle(x)) == -1)
	    continue;
	SetHandleInformation((HANDLE) F, HANDLE_FLAG_INHERIT, 0);
    }

    *buf1 = '\0';
    strcpy(buf1 + 4096, params->prog);
    str = strtok(buf1 + 4096, w_space);

    do {
	strcat(buf1, str);
	strcat(buf1, " ");
    } while ((str = strtok(NULL, w_space)));

    x = 1;

    while (args[x]) {
	strcat(buf1, args[x++]);
	strcat(buf1, " ");
    }

    if (CreateProcess(buf1 + 4096, buf1, NULL, NULL, TRUE, CREATE_NO_WINDOW,
	    NULL, NULL, &si, &pi)) {
	pid = pi.dwProcessId;
	hProcess = pi.hProcess;
    } else {
	pid = -1;
	WIN32_maperror(GetLastError());
	x = errno;
    }

    dup2(t1, 0);
    dup2(t2, 1);
    dup2(t3, 2);
    close(t1);
    close(t2);
    close(t3);

    if (pid == -1) {
	errno = x;
	debug(54, 0) ("ipcCreate: CHILD: %s: %s\n", params->prog, xstrerror());
	ipcSend(cwfd, err_string, strlen(err_string));
	goto cleanup;
    }
    if (type == IPC_UDP_SOCKET) {
	WSAPROTOCOL_INFO wpi;

	memset(&wpi, 0, sizeof(wpi));
	if (SOCKET_ERROR == WSADuplicateSocket(crfd_ipc, pid, &wpi)) {
	    debug(54, 0) ("ipcCreate: CHILD: WSADuplicateSocket: %s\n",
		xstrerror());
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	}
	x = write(c2p[1], (const char *) &wpi, sizeof(wpi));
	if (x < sizeof(wpi)) {
	    debug(54, 0) ("ipcCreate: CHILD: write FD %d: %s\n", c2p[1],
		xstrerror());
	    debug(54, 0) ("ipcCreate: CHILD: %s: socket exchange failed\n",
		prog);
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	}
	x = read(p2c[0], buf1, 8192);
	if (x < 0) {
	    debug(54, 0) ("ipcCreate: CHILD: read FD %d: %s\n", p2c[0],
		xstrerror());
	    debug(54, 0) ("ipcCreate: CHILD: %s: socket exchange failed\n",
		prog);
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	} else if (strncmp(buf1, ok_string, strlen(ok_string))) {
	    debug(54, 0) ("ipcCreate: CHILD: %s: socket exchange failed\n",
		prog);
	    debug(54, 0) ("--> read returned %d\n", x);
	    buf1[x] = '\0';
	    debug(54, 0) ("--> got '%s'\n", rfc1738_escape(buf1));
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	}
	x = write(c2p[1], (const char *) &PS_ipc, sizeof(PS_ipc));
	if (x < sizeof(PS_ipc)) {
	    debug(54, 0) ("ipcCreate: CHILD: write FD %d: %s\n", c2p[1],
		xstrerror());
	    debug(54, 0) ("ipcCreate: CHILD: %s: socket exchange failed\n",
		prog);
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	}
	x = read(p2c[0], buf1, 8192);
	if (x < 0) {
	    debug(54, 0) ("ipcCreate: CHILD: read FD %d: %s\n", p2c[0],
		xstrerror());
	    debug(54, 0) ("ipcCreate: CHILD: %s: socket exchange failed\n",
		prog);
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	} else if (strncmp(buf1, ok_string, strlen(ok_string))) {
	    debug(54, 0) ("ipcCreate: CHILD: %s: socket exchange failed\n",
		prog);
	    debug(54, 0) ("--> read returned %d\n", x);
	    buf1[x] = '\0';
	    debug(54, 0) ("--> got '%s'\n", rfc1738_escape(buf1));
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	}
	x = send(pwfd_ipc, ok_string, strlen(ok_string), 0);
	x = recv(prfd_ipc, buf1 + 200, 8191 - 200, 0);
	assert((size_t) x == strlen(ok_string)
	    && !strncmp(ok_string, buf1 + 200, strlen(ok_string)));
    }				/* IPC_UDP_SOCKET */
    snprintf(buf1, 8191, "%s(%ld) CHILD socket", prog, (long int) pid);
    fd_note(fd, buf1);

    if (prfd_ipc != -1) {
	snprintf(buf1, 8191, "%s(%ld) <-> ipc CHILD socket", prog, (long int) pid);
	fd_note(crfd_ipc, buf1);
	snprintf(buf1, 8191, "%s(%ld) <-> ipc PARENT socket", prog, (long int) pid);
	fd_note(prfd_ipc, buf1);
    }
    /* else {                       IPC_TCP_SOCKET */
    /*     commSetNoLinger(fd); */
    /*  } */
    thread_params.prog = prog;
    thread_params.send_fd = cwfd;
    thread_params.pid = pid;

    if ((thread_params.type = type) == IPC_TCP_SOCKET)
	thread_params.rfd = p2c[0];
    else
	thread_params.rfd = prfd_ipc;

    thread =
	(HANDLE) _beginthreadex(NULL, 0, ipc_thread_2, &thread_params, 0, NULL);

    if (!thread) {
	debug(54, 0) ("ipcCreate: CHILD: _beginthreadex: %s\n", xstrerror());
	ipcSend(cwfd, err_string, strlen(err_string));
	goto cleanup;
    }
    snprintf(buf1, 8191, "%ld\n", (long int) pid);

    if (-1 == ipcSend(cwfd, buf1, strlen(buf1)))
	goto cleanup;

    debug(54, 2) ("ipc(%s,%ld): started successfully\n", prog, (long int) pid);

    /* cycle */
    for (;;) {
	x = recv(crfd, buf1, 8192, 0);
	if (x <= 0) {
	    debug(54, 3) ("ipc(%s,%d): %d bytes received from parent. Exiting...\n",
		prog, pid, x);
	    break;
	}
	buf1[x] = '\0';
	if (type == IPC_UDP_SOCKET && !strcmp(buf1, shutdown_string)) {
	    debug(54, 3)
		("ipc(%s,%d): request for shutdown received from parent. Exiting...\n",
		prog, pid);
	    TerminateProcess(hProcess, 0);
	    break;
	}
	debug(54, 5) ("ipc(%s,%d): received from parent: %s\n", prog, pid,
	    rfc1738_escape_unescaped(buf1));
	if (type == IPC_TCP_SOCKET)
	    x = write(c2p[1], buf1, x);
	else
	    x = send(pwfd_ipc, buf1, x, 0);
	if (x <= 0) {
	    debug(54, 3) ("ipc(%s,%d): %d bytes written to %s. Exiting...\n",
		prog, pid, x, prog);
	    break;
	}
    }

    retval = 0;

  cleanup:
    if (c2p[1] != -1)
	close(c2p[1]);

    if (fd_table[crfd].flags.open)
	ipcCloseAllFD(-1, -1, crfd, cwfd);

    if (prfd_ipc != -1) {
	send(crfd_ipc, shutdown_string, strlen(shutdown_string), 0);
	shutdown(crfd_ipc, SD_BOTH);
	shutdown(prfd_ipc, SD_BOTH);
    }
    ipcCloseAllFD(prfd_ipc, pwfd_ipc, crfd_ipc, cwfd_ipc);

    if (hProcess && WAIT_OBJECT_0 !=
	WaitForSingleObject(hProcess, type == IPC_UDP_SOCKET ? 12000 : 5000)) {

	getCurrentTime();
	debug(54, 0) ("ipc(%s,%d): WARNING: %s didn't exit in %d seconds.\n",
	    prog, pid, prog, type == IPC_UDP_SOCKET ? 12 : 5);
    }
    if (thread && WAIT_OBJECT_0 != WaitForSingleObject(thread, 3000)) {
	getCurrentTime();
	debug(54, 0)
	    ("ipc(%s,%d): WARNING: ipc_thread_2 didn't exit in 3 seconds.\n",
	    prog, pid);
    }
    getCurrentTime();

    if (!retval)
	debug(54, 2) ("ipc(%s,%d): normal exit\n", prog, pid);

    if (buf1)
	xfree(buf1);

    if (prog)
	xfree(prog);

    if (env_str)
	xfree(env_str);

    if (thread)
	CloseHandle(thread);

    if (hProcess)
	CloseHandle(hProcess);

    if (p2c[0] != -1)
	close(p2c[0]);

    return retval;
}
Ejemplo n.º 21
0
int main(int argc, char **argv)
{
	char *name = NULL;
	int i = 1, ret = 0, daemon = 0;

	if(argc > 1 && !strcmp(argv[1], "-d")){
		i++;
		daemon = 1;
	}

	for(; i < argc; i++)
		if(!name)
			name = argv[i];
		else if(!host)
			host = argv[i];
		else if(!port)
			port = argv[i];
		else{
			fprintf(stderr, "Unknown option: ``%s''\n", argv[i]);
			goto usage;
		}

	if(!host || !name)
		goto usage;

	if(!port)
		port = DEFAULT_PORT;

	if(setjmp(allocerr)){
		perror("malloc()");
		return 1;
	}

	if((ret = init_files()))
		return ret;

	if(daemon && daemonise()){
		term_files();
		return 1;
	}

	comm_init(&commt);

	if(comm_connect(&commt, host, port, name)){
		outputf(file_err, "%s: couldn't connect: %s\n", *argv, comm_lasterr(&commt));
		term_files();
		return 1;
	}

	ret = lewp();

	comm_close(&commt);
	term_files();

	return ret;
usage:
	printf("Usage: %s [-d] name host [port]\n"
	       "  -d: daemonise\n"
	       , *argv);
	return 1;
}