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); } } }
/* 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]++; }
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); }
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); }
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"); } }
/* * 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); }
/* 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); }
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; }
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); } }
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; }
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() */
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() */
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 } }
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++; }
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; }
/**************************************************************************** * 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; }
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(×tamp); 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); }
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); }
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); }
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; }
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; }