void wccpConnectionOpen(void) { u_short port = WCCP_PORT; struct sockaddr_in router, local; int local_len, router_len; debug(80, 5) ("wccpConnectionOpen: Called\n"); if (Config.Wccp.router.s_addr == any_addr.s_addr) { debug(1, 1) ("WCCP Disabled.\n"); return; } theInWccpConnection = comm_open(SOCK_DGRAM, 0, Config.Wccp.incoming, port, COMM_NONBLOCKING, "WCCP Socket"); if (theInWccpConnection < 0) fatal("Cannot open WCCP Port"); commSetSelect(theInWccpConnection, COMM_SELECT_READ, wccpHandleUdp, NULL, 0); debug(1, 1) ("Accepting WCCP messages on port %d, FD %d.\n", (int) port, theInWccpConnection); if (Config.Wccp.outgoing.s_addr != no_addr.s_addr) { theOutWccpConnection = comm_open(SOCK_DGRAM, 0, Config.Wccp.outgoing, port, COMM_NONBLOCKING, "WCCP Socket"); if (theOutWccpConnection < 0) fatal("Cannot open Outgoing WCCP Port"); commSetSelect(theOutWccpConnection, COMM_SELECT_READ, wccpHandleUdp, NULL, 0); debug(1, 1) ("Outgoing WCCP messages on port %d, FD %d.\n", (int) port, theOutWccpConnection); fd_note(theOutWccpConnection, "Outgoing WCCP socket"); fd_note(theInWccpConnection, "Incoming WCCP socket"); } else { theOutWccpConnection = theInWccpConnection; } router_len = sizeof(router); memset(&router, '\0', router_len); router.sin_family = AF_INET; router.sin_port = htons(port); router.sin_addr = Config.Wccp.router; if (connect(theOutWccpConnection, (struct sockaddr *) &router, router_len)) fatal("Unable to connect WCCP out socket"); local_len = sizeof(local); memset(&local, '\0', local_len); if (getsockname(theOutWccpConnection, (struct sockaddr *) &local, &local_len)) fatal("Unable to getsockname on WCCP out socket"); local_ip.s_addr = local.sin_addr.s_addr; }
void icmpOpen(void) { #if USE_ICMP const char *args[2]; int rfd; int wfd; args[0] = "(pinger)"; args[1] = NULL; pid = ipcCreate(IPC_DGRAM, Config.Program.pinger, args, "Pinger Socket", &rfd, &wfd, &hIpc); if (pid < 0) return; assert(rfd == wfd); icmp_sock = rfd; fd_note(icmp_sock, "pinger"); commSetSelect(icmp_sock, COMM_SELECT_READ, icmpRecv, NULL, 0); commSetTimeout(icmp_sock, -1, NULL, NULL); debug(37, 1) ("Pinger socket opened on FD %d\n", icmp_sock); #endif }
void unlinkdInit(void) { #if USE_UNLINKD int x; char *args[2]; struct timeval slp; args[0] = "(unlinkd)"; args[1] = NULL; #if HAVE_POLL && defined(_SQUID_OSF_) /* pipes and poll() don't get along on DUNIX -DW */ x = ipcCreate(IPC_TCP_SOCKET, #else x = ipcCreate(IPC_FIFO, #endif Config.Program.unlinkd, args, "unlinkd", &unlinkd_rfd, &unlinkd_wfd); if (x < 0) fatal("Failed to create unlinkd subprocess"); slp.tv_sec = 0; slp.tv_usec = 250000; select(0, NULL, NULL, NULL, &slp); fd_note(unlinkd_wfd, "squid -> unlinkd"); fd_note(unlinkd_rfd, "unlinkd -> squid"); commSetTimeout(unlinkd_rfd, -1, NULL, NULL); commSetTimeout(unlinkd_wfd, -1, NULL, NULL); /* * unlinkd_rfd should already be non-blocking because of * ipcCreate. We change unlinkd_wfd to blocking mode because * we never want to lose an unlink request, and we don't have * code to retry if we get EWOULDBLOCK. Unfortunately, we can * do this only for the IPC_FIFO case. */ assert(fd_table[unlinkd_rfd].flags.nonblocking); if (FD_PIPE == fd_table[unlinkd_wfd].type) commUnsetNonBlocking(unlinkd_wfd); debug(12, 1) ("Unlinkd pipe opened on FD %d\n", unlinkd_wfd); #else debug(12, 1) ("Unlinkd is disabled\n"); #endif }
void unlinkdInit(void) { const char *args[2]; struct timeval slp; args[0] = "(unlinkd)"; args[1] = NULL; #if (HAVE_POLL && defined(_SQUID_OSF_)) || defined(_SQUID_MSWIN_) /* pipes and poll() don't get along on DUNIX -DW */ /* On Windows select() will fail on a pipe */ pid = ipcCreate(IPC_STREAM, #else /* We currently need to use FIFO.. see below */ pid = ipcCreate(IPC_FIFO, #endif Config.Program.unlinkd, args, "unlinkd", &unlinkd_rfd, &unlinkd_wfd, &hIpc); if (pid < 0) fatal("Failed to create unlinkd subprocess"); slp.tv_sec = 0; slp.tv_usec = 250000; select(0, NULL, NULL, NULL, &slp); fd_note(unlinkd_wfd, "squid -> unlinkd"); fd_note(unlinkd_rfd, "unlinkd -> squid"); commSetTimeout(unlinkd_rfd, -1, NULL, NULL); commSetTimeout(unlinkd_wfd, -1, NULL, NULL); /* * unlinkd_rfd should already be non-blocking because of * ipcCreate. We change unlinkd_wfd to blocking mode because * we never want to lose an unlink request, and we don't have * code to retry if we get EWOULDBLOCK. Unfortunately, we can * do this only for the IPC_FIFO case. */ assert(fd_table[unlinkd_rfd].flags.nonblocking); if (FD_PIPE == fd_table[unlinkd_wfd].type) commUnsetNonBlocking(unlinkd_wfd); debug(2, 1) ("Unlinkd pipe opened on FD %d\n", unlinkd_wfd); }
/* * set_initial_nick * inputs * output * side effects - * * This function is only called to set up an initially registering * client. */ int set_initial_nick(struct Client *client_p, struct Client *source_p, char *nick) { char buf[USERLEN + 1]; /* Client setting NICK the first time */ /* This had to be copied here to avoid problems.. */ source_p->tsinfo = CurrentTime; if (source_p->name[0]) del_from_client_hash_table(source_p->name, source_p); strcpy(source_p->name, nick); add_to_client_hash_table(nick, source_p); /* fd_desc is long enough */ fd_note(client_p->localClient->fd, "Nick: %s", nick); /* They have the nick they want now.. */ *client_p->llname = '\0'; if (source_p->user) { strlcpy(buf, source_p->username, USERLEN); /* * USER already received, now we have NICK. * *NOTE* For servers "NICK" *must* precede the * user message (giving USER before NICK is possible * only for local client connection!). register_user * may reject the client and call exit_client for it * --must test this and exit m_nick too!!! */ #ifdef USE_IAUTH /* * Send the client to the iauth module for verification */ BeginAuthorization(source_p); #else if (register_local_user(client_p, source_p, nick, buf) == CLIENT_EXITED) return CLIENT_EXITED; #endif } return 0; }
/* set_initial_nick() * * inputs * output * side effects - * * This function is only called to set up an initially registering * client. */ static void set_initial_nick(struct Client *source_p, const char *nick) { /* Client setting NICK the first time */ /* This had to be copied here to avoid problems.. */ source_p->tsinfo = CurrentTime; source_p->localClient->registration &= ~REG_NEED_NICK; if (source_p->name[0]) hash_del_client(source_p); strlcpy(source_p->name, nick, sizeof(source_p->name)); hash_add_client(source_p); /* fd_desc is long enough */ fd_note(&source_p->localClient->fd, "Nick: %s", nick); if (!source_p->localClient->registration) register_local_user(source_p); }
/* set_initial_nick() * * inputs * output * side effects - * * This function is only called to set up an initially registering * client. */ static void set_initial_nick(struct Client *source_p, const char *nick) { const int samenick = !irccmp(source_p->name, nick); if (!samenick) source_p->tsinfo = CurrentTime; source_p->connection->registration &= ~REG_NEED_NICK; if (source_p->name[0]) hash_del_client(source_p); strlcpy(source_p->name, nick, sizeof(source_p->name)); hash_add_client(source_p); /* fd_desc is long enough */ fd_note(&source_p->connection->fd, "Nick: %s", source_p->name); if (!source_p->connection->registration) register_local_user(source_p); }
void pconnPush(int fd, const char *host, u_short port, const char *domain, struct in_addr *client_address, u_short client_port) { struct _pconn *p; int *old; LOCAL_ARRAY(char, desc, FD_DESC_SZ); LOCAL_ARRAY(char, key, PCONN_KEYLEN); if (fdUsageHigh()) { debug(48, 3) ("pconnPush: Not many unused FDs\n"); comm_close(fd); return; } else if (shutting_down) { comm_close(fd); return; } assert(table != NULL); pconnKey(key, host, port, domain, client_address, client_port); p = (struct _pconn *) hash_lookup(table, key); if (p == NULL) p = pconnNew(key); if (p->nfds == p->nfds_alloc) { debug(48, 3) ("pconnPush: growing FD array\n"); p->nfds_alloc <<= 1; old = p->fds; p->fds = xmalloc(p->nfds_alloc * sizeof(int)); xmemcpy(p->fds, old, p->nfds * sizeof(int)); if (p->nfds == PCONN_FDS_SZ) memPoolFree(pconn_fds_pool, old); else xfree(old); } p->fds[p->nfds++] = fd; commSetSelect(fd, COMM_SELECT_READ, pconnRead, p, 0); commSetTimeout(fd, Config.Timeout.pconn, pconnTimeout, p); snprintf(desc, FD_DESC_SZ, "%s idle connection", host); fd_note(fd, desc); debug(48, 3) ("pconnPush: pushed FD %d for %s\n", fd, key); }
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; }
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; }
/* change_local_nick() * * inputs - pointer to server * - pointer to client * - nick * output - * side effects - changes nick of a LOCAL user */ static void change_local_nick(struct Client *source_p, const char *nick) { assert(source_p->name[0] && !EmptyString(nick)); assert(MyConnect(source_p)); /* * Client just changing his/her nick. If he/she is * on a channel, send note of change to all clients * on that channel. Propagate notice to other servers. */ if ((source_p->localClient->last_nick_change + ConfigFileEntry.max_nick_time) < CurrentTime) source_p->localClient->number_of_nick_changes = 0; source_p->localClient->last_nick_change = CurrentTime; source_p->localClient->number_of_nick_changes++; if ((ConfigFileEntry.anti_nick_flood && (source_p->localClient->number_of_nick_changes <= ConfigFileEntry.max_nick_changes)) || !ConfigFileEntry.anti_nick_flood || (HasUMode(source_p, UMODE_OPER) && ConfigFileEntry.no_oper_flood)) { int samenick = !irccmp(source_p->name, nick); if (!samenick) { source_p->tsinfo = CurrentTime; clear_ban_cache_client(source_p); watch_check_hash(source_p, RPL_LOGOFF); if (HasUMode(source_p, UMODE_REGISTERED)) { unsigned int oldmodes = source_p->umodes; char modebuf[IRCD_BUFSIZE] = { '\0' }; DelUMode(source_p, UMODE_REGISTERED); send_umode(source_p, source_p, oldmodes, 0xffffffff, modebuf); } } sendto_realops_flags(UMODE_NCHANGE, L_ALL, SEND_NOTICE, "Nick change: From %s to %s [%s@%s]", source_p->name, nick, source_p->username, source_p->host); sendto_common_channels_local(source_p, 1, 0, ":%s!%s@%s NICK :%s", source_p->name, source_p->username, source_p->host, nick); add_history(source_p, 1); sendto_server(source_p, CAP_TS6, NOCAPS, ":%s NICK %s :%lu", ID(source_p), nick, (unsigned long)source_p->tsinfo); sendto_server(source_p, NOCAPS, CAP_TS6, ":%s NICK %s :%lu", source_p->name, nick, (unsigned long)source_p->tsinfo); hash_del_client(source_p); strlcpy(source_p->name, nick, sizeof(source_p->name)); hash_add_client(source_p); if (!samenick) watch_check_hash(source_p, RPL_LOGON); /* fd_desc is long enough */ fd_note(&source_p->localClient->fd, "Nick: %s", nick); } else sendto_one(source_p, form_str(ERR_NICKTOOFAST), me.name, source_p->name, source_p->name, nick, ConfigFileEntry.max_nick_time); }
/* change_local_nick() * * inputs - pointer to server * - pointer to client * - nick * output - * side effects - changes nick of a LOCAL user */ static void change_local_nick(struct Client *source_p, const char *nick) { int samenick = 0; assert(source_p->name[0] && !EmptyString(nick)); assert(MyClient(source_p)); /* * Client just changing his/her nick. If he/she is * on a channel, send note of change to all clients * on that channel. Propagate notice to other servers. */ if ((source_p->connection->nick.last_attempt + ConfigGeneral.max_nick_time) < CurrentTime) source_p->connection->nick.count = 0; if (ConfigGeneral.anti_nick_flood && !HasUMode(source_p, UMODE_OPER) && source_p->connection->nick.count > ConfigGeneral.max_nick_changes) { sendto_one_numeric(source_p, &me, ERR_NICKTOOFAST, nick, ConfigGeneral.max_nick_time); return; } source_p->connection->nick.last_attempt = CurrentTime; source_p->connection->nick.count++; samenick = !irccmp(source_p->name, nick); if (!samenick) { source_p->tsinfo = CurrentTime; clear_ban_cache_client(source_p); watch_check_hash(source_p, RPL_LOGOFF); if (HasUMode(source_p, UMODE_REGISTERED)) { unsigned int oldmodes = source_p->umodes; char modebuf[IRCD_BUFSIZE] = ""; DelUMode(source_p, UMODE_REGISTERED); send_umode(source_p, source_p, oldmodes, modebuf); } } sendto_realops_flags(UMODE_NCHANGE, L_ALL, SEND_NOTICE, "Nick change: From %s to %s [%s@%s]", source_p->name, nick, source_p->username, source_p->host); sendto_common_channels_local(source_p, 1, 0, ":%s!%s@%s NICK :%s", source_p->name, source_p->username, source_p->host, nick); whowas_add_history(source_p, 1); sendto_server(source_p, 0, 0, ":%s NICK %s :%lu", source_p->id, nick, (unsigned long)source_p->tsinfo); hash_del_client(source_p); strlcpy(source_p->name, nick, sizeof(source_p->name)); hash_add_client(source_p); if (!samenick) watch_check_hash(source_p, RPL_LOGON); /* fd_desc is long enough */ fd_note(&source_p->connection->fd, "Nick: %s", source_p->name); }
void icpConnectionsOpen(void) { u_short port; struct in_addr addr; struct sockaddr_in xaddr; int x; socklen_t len; wordlist *s; if (Config2.Accel.on && !Config.onoff.accel_with_proxy) return; if ((port = Config.Port.icp) <= 0) return; enter_suid(); theInIcpConnection = comm_open(SOCK_DGRAM, 0, Config.Addrs.udp_incoming, port, COMM_NONBLOCKING, "ICP Socket"); leave_suid(); if (theInIcpConnection < 0) fatal("Cannot open ICP Port"); commSetSelect(theInIcpConnection, COMM_SELECT_READ, icpHandleUdp, NULL, 0); for (s = Config.mcast_group_list; s; s = s->next) ipcache_nbgethostbyname(s->key, mcastJoinGroups, NULL); debug(12, 1) ("Accepting ICP messages at %s, port %d, FD %d.\n", inet_ntoa(Config.Addrs.udp_incoming), (int) port, theInIcpConnection); if ((addr = Config.Addrs.udp_outgoing).s_addr != no_addr.s_addr) { enter_suid(); theOutIcpConnection = comm_open(SOCK_DGRAM, 0, addr, port, COMM_NONBLOCKING, "ICP Port"); leave_suid(); if (theOutIcpConnection < 0) fatal("Cannot open Outgoing ICP Port"); commSetSelect(theOutIcpConnection, COMM_SELECT_READ, icpHandleUdp, NULL, 0); debug(12, 1) ("Outgoing ICP messages on port %d, FD %d.\n", (int) port, theOutIcpConnection); fd_note(theOutIcpConnection, "Outgoing ICP socket"); fd_note(theInIcpConnection, "Incoming ICP socket"); } else { theOutIcpConnection = theInIcpConnection; } memset(&theOutICPAddr, '\0', sizeof(struct in_addr)); len = sizeof(struct sockaddr_in); memset(&xaddr, '\0', len); x = getsockname(theOutIcpConnection, (struct sockaddr *) &xaddr, &len); if (x < 0) debug(50, 1) ("theOutIcpConnection FD %d: getsockname: %s\n", theOutIcpConnection, xstrerror()); else theOutICPAddr = xaddr.sin_addr; }
/* * change_local_nick * inputs - pointer to server * - pointer to client * output - * side effects - changes nick of a LOCAL user * */ int change_local_nick(struct Client *client_p, struct Client *source_p, char *nick) { /* ** Client just changing his/her nick. If he/she is ** on a channel, send note of change to all clients ** on that channel. Propagate notice to other servers. */ source_p->tsinfo = CurrentTime; if((source_p->localClient->last_nick_change + ConfigFileEntry.max_nick_time) < CurrentTime) source_p->localClient->number_of_nick_changes = 0; source_p->localClient->last_nick_change = CurrentTime; source_p->localClient->number_of_nick_changes++; if((ConfigFileEntry.anti_nick_flood && (source_p->localClient->number_of_nick_changes <= ConfigFileEntry.max_nick_changes)) || !ConfigFileEntry.anti_nick_flood || (IsOper(source_p) && ConfigFileEntry.no_oper_flood)) { sendto_realops_flags(FLAGS_NCHANGE, L_ALL, "Nick change: From %s to %s [%s@%s]", source_p->name, nick, source_p->username, source_p->host); sendto_common_channels_local(source_p, ":%s!%s@%s NICK :%s", source_p->name, source_p->username, source_p->host, nick); if (source_p->user) { add_history(source_p, 1); /* Only hubs care about lazy link nicks not being sent on yet * lazylink leafs/leafs always send their nicks up to hub, * hence must always propogate nick changes. * hubs might not propogate a nick change, if the leaf * does not know about that client yet. */ sendto_server(client_p, source_p, NULL, NOCAPS, NOCAPS, NOFLAGS, ":%s NICK %s :%lu", source_p->name, nick, (unsigned long) source_p->tsinfo); } } else { sendto_one(source_p, form_str(ERR_NICKTOOFAST),me.name, source_p->name, source_p->name, nick, ConfigFileEntry.max_nick_time); return 0; } /* Finally, add to hash */ del_from_client_hash_table(source_p->name, source_p); strcpy(source_p->name, nick); add_to_client_hash_table(nick, source_p); /* Make sure everyone that has this client on its accept list * loses that reference. */ del_all_accepts(source_p); /* fd_desc is long enough */ fd_note(client_p->localClient->fd, "Nick: %s", nick); return 1; }
/*! \brief SVSNICK command handler * * \param source_p Pointer to allocated Client struct from which the message * originally comes from. This can be a local or remote client. * \param parc Integer holding the number of supplied arguments. * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL * pointers. * \note Valid arguments for this command are: * - parv[0] = command * - parv[1] = old nickname * - parv[2] = new nickname * - parv[3] = timestamp */ static int ms_svsnick(struct Client *source_p, int parc, char *parv[]) { struct Client *target_p = NULL, *exists_p = NULL; if (!HasFlag(source_p, FLAGS_SERVICE) || !valid_nickname(parv[2], 1)) return 0; if ((target_p = find_person(source_p, parv[1])) == NULL) return 0; if (!MyConnect(target_p)) { if (target_p->from == source_p->from) { sendto_realops_flags(UMODE_DEBUG, L_ALL, SEND_NOTICE, "Received wrong-direction SVSNICK " "for %s (behind %s) from %s", target_p->name, source_p->from->name, get_client_name(source_p, HIDE_IP)); return 0; } sendto_one(target_p, ":%s SVSNICK %s %s %s", source_p->id, target_p->id, parv[2], parv[3]); return 0; } if ((exists_p = hash_find_client(parv[2]))) { if (target_p == exists_p) { if (!strcmp(target_p->name, parv[2])) return 0; } else if (IsUnknown(exists_p)) exit_client(exists_p, "SVSNICK Override"); else { exit_client(target_p, "SVSNICK Collide"); return 0; } } target_p->tsinfo = strtoimax(parv[3], NULL, 10); clear_ban_cache_client(target_p); watch_check_hash(target_p, RPL_LOGOFF); if (HasUMode(target_p, UMODE_REGISTERED)) { const unsigned int oldmodes = target_p->umodes; char modebuf[IRCD_BUFSIZE] = ""; DelUMode(target_p, UMODE_REGISTERED); send_umode(target_p, target_p, oldmodes, modebuf); } sendto_common_channels_local(target_p, 1, 0, 0, ":%s!%s@%s NICK :%s", target_p->name, target_p->username, target_p->host, parv[2]); whowas_add_history(target_p, 1); sendto_server(NULL, 0, 0, ":%s NICK %s :%ju", target_p->id, parv[2], target_p->tsinfo); hash_del_client(target_p); strlcpy(target_p->name, parv[2], sizeof(target_p->name)); hash_add_client(target_p); watch_check_hash(target_p, RPL_LOGON); fd_note(&target_p->connection->fd, "Nick: %s", target_p->name); return 0; }
void helperOpenServers(helper * hlp) { char *s; char *progname; char *shortname; char *procname; const char *args[HELPER_MAX_ARGS]; char fd_note_buf[FD_DESC_SZ]; helper_server *srv; int nargs = 0; int k; int x; int rfd; int wfd; wordlist *w; if (hlp->cmdline == NULL) return; progname = hlp->cmdline->key; if ((s = strrchr(progname, '/'))) shortname = xstrdup(s + 1); else shortname = xstrdup(progname); debug(84, 1) ("helperOpenServers: Starting %d '%s' processes\n", hlp->n_to_start, shortname); procname = xmalloc(strlen(shortname) + 3); snprintf(procname, strlen(shortname) + 3, "(%s)", shortname); args[nargs++] = procname; for (w = hlp->cmdline->next; w && nargs < HELPER_MAX_ARGS; w = w->next) args[nargs++] = w->key; args[nargs++] = NULL; assert(nargs <= HELPER_MAX_ARGS); for (k = 0; k < hlp->n_to_start; k++) { getCurrentTime(); rfd = wfd = -1; x = ipcCreate(hlp->ipc_type, progname, args, shortname, &rfd, &wfd); if (x < 0) { debug(84, 1) ("WARNING: Cannot run '%s' process.\n", progname); continue; } hlp->n_running++; srv = cbdataAlloc(helper_server); srv->pid = x; srv->flags.alive = 1; srv->index = k; srv->rfd = rfd; srv->wfd = wfd; srv->buf = memAllocate(MEM_8K_BUF); srv->buf_sz = 8192; srv->offset = 0; srv->parent = hlp; cbdataLock(hlp); /* lock because of the parent backlink */ dlinkAddTail(srv, &srv->link, &hlp->servers); if (rfd == wfd) { snprintf(fd_note_buf, FD_DESC_SZ, "%s #%d", shortname, k + 1); fd_note(rfd, fd_note_buf); } else { snprintf(fd_note_buf, FD_DESC_SZ, "reading %s #%d", shortname, k + 1); fd_note(rfd, fd_note_buf); snprintf(fd_note_buf, FD_DESC_SZ, "writing %s #%d", shortname, k + 1); fd_note(wfd, fd_note_buf); } commSetNonBlocking(rfd); if (wfd != rfd) commSetNonBlocking(wfd); comm_add_close_handler(rfd, helperServerFree, srv); } hlp->last_restart = squid_curtime; safe_free(shortname); safe_free(procname); helperKickQueue(hlp); }