static void do_create_connects(struct sockaddr_in *servaddr, int nums) { int fd; struct socket *sock; struct sockaddr cliaddr; int i; for (i = 0; i < nums; i++) { fd = lkm_create_tcp_connect(servaddr); if (fd < 0) break; sock = getsock(fd); if (!sock) break; if (!getsockcliaddr(sock, &cliaddr)) break; if (insert_sock_to_sockp(&cliaddr, (struct sockaddr *)servaddr, sock, fd, SOCK_PRECONNECT, NULL) != KCP_OK) { orig_sys_close(fd); break; } } return; }
int getifflags(prop_dictionary_t env, prop_dictionary_t oenv, unsigned short *flagsp) { struct ifreq ifr; const char *ifname; uint64_t ifflags; int s; if (prop_dictionary_get_uint64(env, "ifflags", &ifflags)) { *flagsp = (unsigned short)ifflags; return 0; } if ((s = getsock(AF_UNSPEC)) == -1) return -1; if ((ifname = getifname(env)) == NULL) return -1; memset(&ifr, 0, sizeof(ifr)); estrlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) return -1; *flagsp = (unsigned short)ifr.ifr_flags; prop_dictionary_set_uint64(oenv, "ifflags", (unsigned short)ifr.ifr_flags); return 0; }
/* ARGSUSED */ int sys_getpeername(struct proc *p, void *v, register_t *retval) { struct sys_getpeername_args /* { syscallarg(int) fdes; syscallarg(struct sockaddr *) asa; syscallarg(socklen_t *) alen; } */ *uap = v; struct file *fp; struct socket *so; struct mbuf *m = NULL; socklen_t len; int error; if ((error = getsock(p->p_fd, SCARG(uap, fdes), &fp)) != 0) return (error); so = fp->f_data; if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) { FRELE(fp, p); return (ENOTCONN); } error = copyin(SCARG(uap, alen), &len, sizeof (len)); if (error) goto bad; m = m_getclr(M_WAIT, MT_SONAME); error = (*so->so_proto->pr_usrreq)(so, PRU_PEERADDR, 0, m, 0, p); if (error) goto bad; error = copyaddrout(p, m, SCARG(uap, asa), len, SCARG(uap, alen)); bad: FRELE(fp, p); m_freem(m); return (error); }
/* ARGSUSED */ int sys_bind(struct proc *p, void *v, register_t *retval) { struct sys_bind_args /* { syscallarg(int) s; syscallarg(const struct sockaddr *) name; syscallarg(socklen_t) namelen; } */ *uap = v; struct file *fp; struct mbuf *nam; int error; if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0) return (error); error = sockargs(&nam, SCARG(uap, name), SCARG(uap, namelen), MT_SONAME); if (error == 0) { #ifdef KTRACE if (KTRPOINT(p, KTR_STRUCT)) ktrsockaddr(p, mtod(nam, caddr_t), SCARG(uap, namelen)); #endif error = sobind(fp->f_data, nam, p); m_freem(nam); } FRELE(fp, p); return (error); }
int doit( int port) { fd_set needread; /* for seeing which fds we need to read from */ sock = getsock(sendbuf, port); printf("ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\r\n"); printf("º (dialin.exe) v0.08a º\r\n"); printf("º compiled with Cset v2.1 º\r\n"); printf("º (c) 1995 Stephen Loomis º\r\n"); printf("ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\r\n"); while (1 == 1) { FD_ZERO(&needread); FD_SET(sock, &needread); if (select(sizeof(fd_set), &needread, (fd_set *)0, (fd_set *)0, (struct timeval *)0) == -1) { if (errno != EINTR) { continue; } else continue; /* do it again and get it right */ } if (FD_ISSET(sock, &needread)) { y=0;cat=0;dog=0;total=0; conn = newconn(sock); } } }
void check_maxfiles() { int sock = -1, sock1 = -1 , bogus = 0, failed_close = 0; #ifdef USE_IPV6 sock1 = getsock(0, AF_INET); /* fill up any lower avail */ sock = getsock(0, AF_INET); #else sock1 = getsock(0); sock = getsock(0); #endif if (sock1 != -1) killsock(sock1); if (sock == -1) { return; } else killsock(sock); bogus = sock - socks_total - 4; //4 for stdin/stdout/stderr/dns if (bogus >= 50) { /* Attempt to close them */ sdprintf("SOCK: %d BOGUS: %d SOCKS_TOTAL: %d", sock, bogus, socks_total); for (int i = 10; i < sock; i++) /* dont close lower sockets, they're probably legit */ if (!findanysnum(i)) { if ((close(i)) == -1) /* try to close the BOGUS fd (likely a KQUEUE) */ failed_close++; else bogus--; } if (bogus >= 150 || failed_close >= 50) { if (tands > 0) { botnet_send_chat(-1, conf.bot->nick, "Max FD reached, restarting..."); botnet_send_bye("Max FD reached, restarting..."); } nuke_server("brb"); cycle_time = 0; restart(-1); } else if (bogus >= 100 && (bogus % 10) == 0) { putlog(LOG_WARN, "*", "* WARNING: $b%d$b bogus file descriptors detected, auto restart at 150", bogus); } } }
/* ARGSUSED */ int sys_connect(struct proc *p, void *v, register_t *retval) { struct sys_connect_args /* { syscallarg(int) s; syscallarg(const struct sockaddr *) name; syscallarg(socklen_t) namelen; } */ *uap = v; struct file *fp; struct socket *so; struct mbuf *nam = NULL; int error, s; if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0) return (error); so = fp->f_data; if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) { FRELE(fp, p); return (EALREADY); } error = sockargs(&nam, SCARG(uap, name), SCARG(uap, namelen), MT_SONAME); if (error) goto bad; #ifdef KTRACE if (KTRPOINT(p, KTR_STRUCT)) ktrsockaddr(p, mtod(nam, caddr_t), SCARG(uap, namelen)); #endif error = soconnect(so, nam); if (error) goto bad; if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) { FRELE(fp, p); m_freem(nam); return (EINPROGRESS); } s = splsoftnet(); while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) { error = tsleep(&so->so_timeo, PSOCK | PCATCH, "netcon2", 0); if (error) break; } if (error == 0) { error = so->so_error; so->so_error = 0; } splx(s); bad: so->so_state &= ~SS_ISCONNECTING; FRELE(fp, p); if (nam) m_freem(nam); if (error == ERESTART) error = EINTR; return (error); }
void print_link_addresses(prop_dictionary_t env, bool print_active_only) { char hbuf[NI_MAXHOST]; const char *ifname; int s; struct ifaddrs *ifa, *ifap; const struct sockaddr_dl *sdl; struct if_laddrreq iflr; if ((ifname = getifname(env)) == NULL) err(EXIT_FAILURE, "%s: getifname", __func__); if ((s = getsock(AF_LINK)) == -1) err(EXIT_FAILURE, "%s: getsock", __func__); if (getifaddrs(&ifap) == -1) err(EXIT_FAILURE, "%s: getifaddrs", __func__); memset(&iflr, 0, sizeof(iflr)); strlcpy(iflr.iflr_name, ifname, sizeof(iflr.iflr_name)); for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { if (strcmp(ifname, ifa->ifa_name) != 0) continue; if (ifa->ifa_addr->sa_family != AF_LINK) continue; sdl = satocsdl(ifa->ifa_addr); memcpy(&iflr.addr, ifa->ifa_addr, MIN(ifa->ifa_addr->sa_len, sizeof(iflr.addr))); iflr.flags = IFLR_PREFIX; iflr.prefixlen = sdl->sdl_alen * NBBY; if (prog_ioctl(s, SIOCGLIFADDR, &iflr) == -1) err(EXIT_FAILURE, "%s: ioctl", __func__); if (((iflr.flags & IFLR_ACTIVE) != 0) != print_active_only) continue; if (getnameinfo(ifa->ifa_addr, ifa->ifa_addr->sa_len, hbuf, sizeof(hbuf), NULL, 0, Nflag ? 0 : NI_NUMERICHOST) == 0 && hbuf[0] != '\0') { printf("\t%s %s\n", print_active_only ? "address:" : "link", hbuf); } } freeifaddrs(ifap); }
/* ARGSUSED */ int sys_setsockopt(struct proc *p, void *v, register_t *retval) { struct sys_setsockopt_args /* { syscallarg(int) s; syscallarg(int) level; syscallarg(int) name; syscallarg(const void *) val; syscallarg(socklen_t) valsize; } */ *uap = v; struct file *fp; struct mbuf *m = NULL; int error; if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0) return (error); if (SCARG(uap, valsize) > MCLBYTES) { error = EINVAL; goto bad; } if (SCARG(uap, val)) { m = m_get(M_WAIT, MT_SOOPTS); if (SCARG(uap, valsize) > MLEN) { MCLGET(m, M_DONTWAIT); if ((m->m_flags & M_EXT) == 0) { error = ENOBUFS; goto bad; } } if (m == NULL) { error = ENOBUFS; goto bad; } error = copyin(SCARG(uap, val), mtod(m, caddr_t), SCARG(uap, valsize)); if (error) { goto bad; } m->m_len = SCARG(uap, valsize); } error = sosetopt(fp->f_data, SCARG(uap, level), SCARG(uap, name), m); m = NULL; bad: if (m) m_freem(m); FRELE(fp, p); return (error); }
/* ARGSUSED */ int sys_shutdown(struct proc *p, void *v, register_t *retval) { struct sys_shutdown_args /* { syscallarg(int) s; syscallarg(int) how; } */ *uap = v; struct file *fp; int error; if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0) return (error); error = soshutdown(fp->f_data, SCARG(uap, how)); FRELE(fp, p); return (error); }
int direct_ioctl(prop_dictionary_t env, unsigned long cmd, void *data) { const char *ifname; int s; if ((s = getsock(AF_UNSPEC)) == -1) err(EXIT_FAILURE, "getsock"); if ((ifname = getifname(env)) == NULL) err(EXIT_FAILURE, "getifname"); estrlcpy(data, ifname, IFNAMSIZ); return prog_ioctl(s, cmd, data); }
void proto_connect() { { struct addrinfo *info = get_addr_info(bot->host, bot->port); bot->socket = getsock(info); fcntl(bot->socket, F_SETFL, O_NONBLOCK); bot->running = 1; // we won't need this anymore. freeaddrinfo(info); } printf("[irc\tinfo] registering with the server.\n"); sockprintf(bot->socket, "NICK %s", bot->nick); sockprintf(bot->socket, "USER apollo * * :hi i'm apollo"); }
static void server_resolve_success(int servidx) { char pass[121]; resolvserv = 0; strcpy(pass, dcc[servidx].u.dns->cbuf); changeover_dcc(servidx, &SERVER_SOCKET, 0); dcc[servidx].sock = getsock(dcc[servidx].sockname.family, 0); setsnport(dcc[servidx].sockname, dcc[servidx].port); serv = open_telnet_raw(dcc[servidx].sock, &dcc[servidx].sockname); if (serv < 0) { putlog(LOG_SERV, "*", "%s %s (%s)", IRC_FAILEDCONNECT, dcc[servidx].host, strerror(errno)); lostdcc(servidx); return; } #ifdef TLS if (dcc[servidx].ssl && ssl_handshake(serv, TLS_CONNECT, tls_vfyserver, LOG_SERV, dcc[servidx].host, NULL)) { putlog(LOG_SERV, "*", "%s %s (%s)", IRC_FAILEDCONNECT, dcc[servidx].host, "TLS negotiation failure"); lostdcc(servidx); return; } #endif /* Queue standard login */ dcc[servidx].timeval = now; SERVER_SOCKET.timeout_val = &server_timeout; /* Another server may have truncated it, so use the original */ strcpy(botname, origbotname); /* Start alternate nicks from the beginning */ altnick_char = 0; if (pass[0]) dprintf(DP_MODE, "PASS %s\n", pass); dprintf(DP_MODE, "NICK %s\n", botname); rmspace(botrealname); if (botrealname[0] == 0) strcpy(botrealname, "/msg LamestBot hello"); dprintf(DP_MODE, "USER %s . . :%s\n", botuser, botrealname); /* Wait for async result now. */ }
static int contact( char *dirc ) { int s = 0; int sock; while ( s < nlocks && strcmp( mylock[s].directory, dirc ) ) s++; if ( s == nlocks ) { /* not in list */ mylock = realloc( mylock, sizeof( lock_struct ) * ++nlocks ); strcpy( mylock[s].directory, dirc ); mylock[s].locks = 0; } else if ( mylock[s].locks ) { /* still open */ return( s ); } if ( ( sock = getsock( dirc ) ) < 0 ) { /* get socket */ return( sock ); /* error */ } else { /* done */ mylock[s].sock = sock; return( s ); } }
int16_t ifa_get_preference(const char *ifname, const struct sockaddr *sa) { struct if_addrprefreq ifap; int s; if ((s = getsock(sa->sa_family)) == -1) { if (errno == EPROTONOSUPPORT) return 0; err(EXIT_FAILURE, "socket"); } memset(&ifap, 0, sizeof(ifap)); estrlcpy(ifap.ifap_name, ifname, sizeof(ifap.ifap_name)); memcpy(&ifap.ifap_addr, sa, MIN(sizeof(ifap.ifap_addr), sa->sa_len)); if (prog_ioctl(s, SIOCGIFADDRPREF, &ifap) == -1) { if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) return 0; warn("SIOCGIFADDRPREF"); } return ifap.ifap_preference; }
int sendm(Mail mail) { sock soc; int i; char req[6][1024]; sprintf(req[0], "helo bamboo-copter.com\r\n"); sprintf(req[1], "mail from:%s\r\n", mail.from); sprintf(req[2], "rcpt to:%s\r\n", mail.to); sprintf(req[3], "data\r\n"); sprintf(req[4], "From: %s\nSubject: %s\n%s\r\n.\r\n", mail.from, mail.subject, mail.message); sprintf(req[5], "quit\r\n"); soc = getsock(mail.serv, mail.port); for(i = 0; i < (sizeof(req) / sizeof(req[0])); request(soc, req[i++])); sclose(soc); return 0; }
/* ARGSUSED */ int sys_getsockopt(struct proc *p, void *v, register_t *retval) { struct sys_getsockopt_args /* { syscallarg(int) s; syscallarg(int) level; syscallarg(int) name; syscallarg(void *) val; syscallarg(socklen_t *) avalsize; } */ *uap = v; struct file *fp; struct mbuf *m = NULL; socklen_t valsize; int error; if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0) return (error); if (SCARG(uap, val)) { error = copyin(SCARG(uap, avalsize), &valsize, sizeof (valsize)); if (error) goto out; } else valsize = 0; if ((error = sogetopt(fp->f_data, SCARG(uap, level), SCARG(uap, name), &m)) == 0 && SCARG(uap, val) && valsize && m != NULL) { if (valsize > m->m_len) valsize = m->m_len; error = copyout(mtod(m, caddr_t), SCARG(uap, val), valsize); if (error == 0) error = copyout(&valsize, SCARG(uap, avalsize), sizeof (valsize)); } out: FRELE(fp, p); if (m != NULL) (void)m_free(m); return (error); }
static int tcl_connect(ClientData cd, Tcl_Interp *irp, int argc, char *argv[]) { int i, z, sock; char s[81]; BADARGS(3, 3, " hostname port"); if (dcc_total == max_dcc) { Tcl_AppendResult(irp, "out of dcc table space", NULL); return TCL_ERROR; } sock = getsock(0); if (sock < 0) { Tcl_AppendResult(irp, MISC_NOFREESOCK, NULL); return TCL_ERROR; } z = open_telnet_raw(sock, argv[1], atoi(argv[2])); if (z < 0) { killsock(sock); if (z == -2) strncpyz(s, "DNS lookup failed", sizeof s); else neterror(s); Tcl_AppendResult(irp, s, NULL); return TCL_ERROR; } i = new_dcc(&DCC_SOCKET, 0); dcc[i].sock = sock; dcc[i].port = atoi(argv[2]); strcpy(dcc[i].nick, "*"); strncpyz(dcc[i].host, argv[1], UHOSTMAX); egg_snprintf(s, sizeof s, "%d", sock); Tcl_AppendResult(irp, s, NULL); return TCL_OK; }
static void failed_tandem_relay(int idx) { int uidx = (-1), i; Context; for (i = 0; i < dcc_total; i++) if ((dcc[i].type == &DCC_PRE_RELAY) && (dcc[i].u.relay->sock == dcc[idx].sock)) uidx = i; if (uidx < 0) { putlog(LOG_MISC, "*", "%s %d -> %d", BOT_CANTFINDRELAYUSER, dcc[idx].sock, dcc[idx].u.relay->sock); killsock(dcc[idx].sock); lostdcc(idx); return; } if (dcc[idx].port >= dcc[idx].u.relay->port + 3) { struct chat_info *ci = dcc[uidx].u.relay->chat; dprintf(uidx, "%s %s.\n", BOT_CANTLINKTO, dcc[idx].nick); dcc[uidx].status = dcc[uidx].u.relay->old_status; nfree(dcc[uidx].u.relay); dcc[uidx].u.chat = ci; dcc[uidx].type = &DCC_CHAT; killsock(dcc[idx].sock); lostdcc(idx); return; } killsock(dcc[idx].sock); dcc[idx].sock = getsock(SOCK_STRONGCONN); dcc[uidx].u.relay->sock = dcc[idx].sock; dcc[idx].port++; dcc[idx].timeval = now; if (open_telnet_raw(dcc[idx].sock, dcc[idx].host, dcc[idx].port) < 0) failed_tandem_relay(idx); }
/* link to another bot */ int botlink(char *linker, int idx, char *nick) { struct bot_addr *bi; struct userrec *u; register int i; Context; u = get_user_by_handle(userlist, nick); if (!u || !(u->flags & USER_BOT)) { if (idx >= 0) dprintf(idx, "%s %s\n", nick, BOT_BOTUNKNOWN); } else if (!strcasecmp(nick, botnetnick)) { if (idx >= 0) dprintf(idx, "%s\n", BOT_CANTLINKMYSELF); } else if (in_chain(nick) && (idx != -3)) { if (idx >= 0) dprintf(idx, "%s\n", BOT_ALREADYLINKED); } else { for (i = 0; i < dcc_total; i++) if ((dcc[i].user == u) && ((dcc[i].type == &DCC_FORK_BOT) || (dcc[i].type == &DCC_BOT_NEW))) { if (idx >= 0) dprintf(idx, "%s\n", BOT_ALREADYLINKING); return 0; } /* address to connect to is in 'info' */ bi = (struct bot_addr *) get_user(&USERENTRY_BOTADDR, u); if (!bi || !strlen(bi->address) || !bi->telnet_port) { if (idx >= 0) { dprintf(idx, "%s '%s'.\n", BOT_NOTELNETADDY, nick); dprintf(idx, "%s .chaddr %s %s\n", MISC_USEFORMAT, nick, MISC_CHADDRFORMAT); } } else if (dcc_total == max_dcc) { if (idx >= 0) dprintf(idx, "%s\n", DCC_TOOMANYDCCS1); } else { Context; correct_handle(nick); i = new_dcc(&DCC_FORK_BOT, sizeof(struct bot_info)); dcc[i].port = bi->telnet_port; strcpy(dcc[i].nick, nick); strcpy(dcc[i].host, bi->address); dcc[i].timeval = now; strcpy(dcc[i].u.bot->linker, linker); strcpy(dcc[i].u.bot->version, "(primitive bot)"); if (idx > -2) putlog(LOG_BOTS, "*", "%s %s at %s:%d ...", BOT_LINKING, nick, bi->address, bi->telnet_port); dcc[i].u.bot->numver = idx; dcc[i].timeval = now; dcc[i].u.bot->port = dcc[i].port; /* remember where i started */ dcc[i].sock = getsock(SOCK_STRONGCONN); dcc[i].user = u; if (open_telnet_raw(dcc[i].sock, bi->address, dcc[i].port) < 0) failed_link(i); return 1; } } return 0; }
static void filesys_dcc_send_hostresolved(int i) { char *s1, *param, prt[100], ip[100], *tempf; int len = dcc[i].u.dns->ibuf, j; sprintf(prt, "%d", dcc[i].port); sprintf(ip, "%lu", iptolong(htonl(dcc[i].addr))); if (!hostsanitycheck_dcc(dcc[i].nick, dcc[i].u.dns->host, dcc[i].addr, dcc[i].u.dns->host, prt)) { lostdcc(i); return; } param = nmalloc(strlen(dcc[i].u.dns->cbuf) + 1); strcpy(param, dcc[i].u.dns->cbuf); changeover_dcc(i, &DCC_FORK_SEND, sizeof(struct xfer_info)); if (param[0] == '.') param[0] = '_'; /* Save the original filename */ dcc[i].u.xfer->origname = get_data_ptr(strlen(param) + 1); strcpy(dcc[i].u.xfer->origname, param); tempf = mktempfile(param); dcc[i].u.xfer->filename = get_data_ptr(strlen(tempf) + 1); strcpy(dcc[i].u.xfer->filename, tempf); /* We don't need the temporary buffers anymore */ my_free(tempf); my_free(param); if (upload_to_cd) { char *p = get_user(&USERENTRY_DCCDIR, dcc[i].user); if (p) sprintf(dcc[i].u.xfer->dir, "%s%s/", dccdir, p); else sprintf(dcc[i].u.xfer->dir, "%s", dccdir); } else strcpy(dcc[i].u.xfer->dir, dccin); dcc[i].u.xfer->length = len; s1 = nmalloc(strlen(dcc[i].u.xfer->dir) + strlen(dcc[i].u.xfer->origname) + 1); sprintf(s1, "%s%s", dcc[i].u.xfer->dir, dcc[i].u.xfer->origname); if (file_readable(s1)) { dprintf(DP_HELP, "NOTICE %s :File `%s' already exists.\n", dcc[i].nick, dcc[i].u.xfer->origname); lostdcc(i); my_free(s1); } else { my_free(s1); /* Check for dcc-sends in process with the same filename */ for (j = 0; j < dcc_total; j++) if (j != i) { if ((dcc[j].type->flags & (DCT_FILETRAN | DCT_FILESEND)) == (DCT_FILETRAN | DCT_FILESEND)) { if (!strcmp(dcc[i].u.xfer->origname, dcc[j].u.xfer->origname)) { dprintf(DP_HELP, "NOTICE %s :File `%s' is already being sent.\n", dcc[i].nick, dcc[i].u.xfer->origname); lostdcc(i); return; } } } /* Put uploads in /tmp first */ s1 = nmalloc(strlen(tempdir) + strlen(dcc[i].u.xfer->filename) + 1); sprintf(s1, "%s%s", tempdir, dcc[i].u.xfer->filename); dcc[i].u.xfer->f = fopen(s1, "w"); my_free(s1); if (dcc[i].u.xfer->f == NULL) { dprintf(DP_HELP, "NOTICE %s :Can't create file `%s' (temp dir error)\n", dcc[i].nick, dcc[i].u.xfer->origname); lostdcc(i); } else { dcc[i].timeval = now; dcc[i].sock = getsock(SOCK_BINARY); if (dcc[i].sock < 0 || open_telnet_dcc(dcc[i].sock, ip, prt) < 0) dcc[i].type->eof(i); } } }
int sys_accept(struct proc *p, void *v, register_t *retval) { struct sys_accept_args /* { syscallarg(int) s; syscallarg(struct sockaddr *) name; syscallarg(socklen_t *) anamelen; } */ *uap = v; struct file *fp, *headfp; struct mbuf *nam; socklen_t namelen; int error, s, tmpfd; struct socket *head, *so; int nflag; if (SCARG(uap, name) && (error = copyin(SCARG(uap, anamelen), &namelen, sizeof (namelen)))) return (error); if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0) return (error); headfp = fp; s = splsoftnet(); head = fp->f_data; redo: if ((head->so_options & SO_ACCEPTCONN) == 0) { error = EINVAL; goto bad; } if ((head->so_state & SS_NBIO) && head->so_qlen == 0) { if (head->so_state & SS_CANTRCVMORE) error = ECONNABORTED; else error = EWOULDBLOCK; goto bad; } while (head->so_qlen == 0 && head->so_error == 0) { if (head->so_state & SS_CANTRCVMORE) { head->so_error = ECONNABORTED; break; } error = tsleep(&head->so_timeo, PSOCK | PCATCH, "netcon", 0); if (error) { goto bad; } } if (head->so_error) { error = head->so_error; head->so_error = 0; goto bad; } /* Take note if socket was non-blocking. */ nflag = (headfp->f_flag & FNONBLOCK); fdplock(p->p_fd); error = falloc(p, &fp, &tmpfd); fdpunlock(p->p_fd); if (error != 0) { /* * Probably ran out of file descriptors. Wakeup * so some other process might have a chance at it. */ wakeup_one(&head->so_timeo); goto bad; } nam = m_get(M_WAIT, MT_SONAME); /* * Check whether the queue emptied while we slept: falloc() or * m_get() may have blocked, allowing the connection to be reset * or another thread or process to accept it. If so, start over. */ if (head->so_qlen == 0) { m_freem(nam); fdplock(p->p_fd); fdremove(p->p_fd, tmpfd); closef(fp, p); fdpunlock(p->p_fd); goto redo; } /* * Do not sleep after we have taken the socket out of the queue. */ so = TAILQ_FIRST(&head->so_q); if (soqremque(so, 1) == 0) panic("accept"); /* connection has been removed from the listen queue */ KNOTE(&head->so_rcv.sb_sel.si_note, 0); fp->f_type = DTYPE_SOCKET; fp->f_flag = FREAD | FWRITE | nflag; fp->f_ops = &socketops; fp->f_data = so; error = soaccept(so, nam); if (!error && SCARG(uap, name)) { error = copyaddrout(p, nam, SCARG(uap, name), namelen, SCARG(uap, anamelen)); } if (error) { /* if an error occurred, free the file descriptor */ fdplock(p->p_fd); fdremove(p->p_fd, tmpfd); closef(fp, p); fdpunlock(p->p_fd); } else { FILE_SET_MATURE(fp, p); *retval = tmpfd; } m_freem(nam); bad: splx(s); FRELE(headfp, p); return (error); }
int sendit(struct proc *p, int s, struct msghdr *mp, int flags, register_t *retsize) { struct file *fp; struct uio auio; struct iovec *iov; int i; struct mbuf *to, *control; size_t len; int error; #ifdef KTRACE struct iovec *ktriov = NULL; #endif to = NULL; if ((error = getsock(p->p_fd, s, &fp)) != 0) return (error); auio.uio_iov = mp->msg_iov; auio.uio_iovcnt = mp->msg_iovlen; auio.uio_segflg = UIO_USERSPACE; auio.uio_rw = UIO_WRITE; auio.uio_procp = p; auio.uio_offset = 0; /* XXX */ auio.uio_resid = 0; iov = mp->msg_iov; for (i = 0; i < mp->msg_iovlen; i++, iov++) { /* Don't allow sum > SSIZE_MAX */ if (iov->iov_len > SSIZE_MAX || (auio.uio_resid += iov->iov_len) > SSIZE_MAX) { error = EINVAL; goto bad; } } if (mp->msg_name) { error = sockargs(&to, mp->msg_name, mp->msg_namelen, MT_SONAME); if (error) goto bad; #ifdef KTRACE if (KTRPOINT(p, KTR_STRUCT)) ktrsockaddr(p, mtod(to, caddr_t), mp->msg_namelen); #endif } if (mp->msg_control) { if (mp->msg_controllen < CMSG_ALIGN(sizeof(struct cmsghdr))) { error = EINVAL; goto bad; } error = sockargs(&control, mp->msg_control, mp->msg_controllen, MT_CONTROL); if (error) goto bad; } else control = 0; #ifdef KTRACE if (KTRPOINT(p, KTR_GENIO)) { int iovlen = auio.uio_iovcnt * sizeof (struct iovec); ktriov = malloc(iovlen, M_TEMP, M_WAITOK); bcopy(auio.uio_iov, ktriov, iovlen); } #endif len = auio.uio_resid; error = sosend(fp->f_data, to, &auio, NULL, control, flags); if (error) { if (auio.uio_resid != len && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) error = 0; if (error == EPIPE && (flags & MSG_NOSIGNAL) == 0) ptsignal(p, SIGPIPE, STHREAD); } if (error == 0) { *retsize = len - auio.uio_resid; fp->f_wxfer++; fp->f_wbytes += *retsize; } #ifdef KTRACE if (ktriov != NULL) { if (error == 0) ktrgenio(p, s, UIO_WRITE, ktriov, *retsize); free(ktriov, M_TEMP); } #endif bad: FRELE(fp, p); if (to) m_freem(to); return (error); }
/* * RFC 3542 IPV6_PKTINFO not in mainline yet (as of 2.6.15). The get/set * tests are below, and comments for some further tests to be added later */ void test_pktinfo(void) { int s_snd, s_rcv[3] = { -1, -1, -1 }; struct sockaddr_in6 sa_rcv[3]; int s, i; struct ifaddrs *pifa_head, *pifa; struct sockaddr_in6 *psin6; char strbuf[128]; char *tname = "IPV6_PKTINFO"; struct in6_pktinfo pi, pi_tmp; int sinlen; int optlen; s_snd = getsock(tname, 0, IPV6_ADDR_GLOBAL); if (s_snd < 0) { tst_resm(TBROK, "%s: can't create send socket", tname); return; } /* global-scope address, interface X */ sa_rcv[0].sin6_scope_id = 0; s_rcv[0] = getsock(tname, &sa_rcv[0], IPV6_ADDR_GLOBAL); if (s_rcv[0] == -1) { tst_resm(TBROK, "%s: only link-scope addresses", tname); return; } /* link-local-scope address, interface X */ sa_rcv[1].sin6_scope_id = sa_rcv[0].sin6_scope_id; s_rcv[1] = getsock(tname, &sa_rcv[1], IPV6_ADDR_LINK); if (s_rcv[1] < 0) { tst_resm(TBROK, "%s: no link-local address on ifindex %d", tname, sa_rcv[0].sin6_scope_id); return; } /* link-local-scope address, interface Y */ sa_rcv[2].sin6_scope_id = -sa_rcv[0].sin6_scope_id; s_rcv[2] = getsock(tname, &sa_rcv[2], IPV6_ADDR_LINK); if (s_rcv[2] < 0) { tst_resm(TBROK, "%s: only one interface?", tname); return; } /* send to rcv1 to verify communication */ /* force to rcv2 w/ PKTINFO */ /* TESTS: */ /* sticky set-get */ tname = "IPV6_PKTINFO set"; pi.ipi6_addr = sa_rcv[1].sin6_addr; pi.ipi6_ifindex = sa_rcv[1].sin6_scope_id; TEST(setsockopt(s_snd, SOL_IPV6, IPV6_PKTINFO, &pi, sizeof(pi))); if (TEST_RETURN != 0) tst_resm(TFAIL, "%s: %s", tname, strerror(errno)); else tst_resm(TPASS, "%s", tname); tname = "IPV6_PKTINFO get"; optlen = sizeof(pi_tmp); TEST(getsockopt(s_snd, SOL_IPV6, IPV6_PKTINFO, &pi_tmp, &optlen)); if (TEST_RETURN != 0) tst_resm(TFAIL, "%s: %s", tname, strerror(errno)); else if (memcmp(&pi, &pi_tmp, sizeof(pi)) != 0) { char strbuf2[64]; tst_resm(TFAIL, "%s: {\"%s\",%d} != {\"%s\",%d}", tname, inet_ntop(AF_INET6, &pi_tmp.ipi6_addr, strbuf, sizeof(strbuf)), pi_tmp.ipi6_ifindex, inet_ntop(AF_INET6, &pi.ipi6_addr, strbuf2, sizeof(strbuf2)), pi.ipi6_ifindex); } else tst_resm(TPASS, "%s", tname); /* ancillary data override */ /* link-local, wrong interface */ tname = "IPV6_PKTINFO invalid {lladdr, intf}"; pi.ipi6_addr = sa_rcv[1].sin6_addr; pi.ipi6_ifindex = sa_rcv[2].sin6_scope_id; TEST(setsockopt(s_snd, SOL_IPV6, IPV6_PKTINFO, &pi, sizeof(pi))); if (TEST_RETURN == 0) tst_resm(TFAIL, "%s returns success, should be -1, EINVAL", tname); else if (TEST_ERRNO != EINVAL) tst_resm(TFAIL, "%s errno %d != %d", tname, TEST_ERRNO, EINVAL); else tst_resm(TPASS, "%s", tname); /* nonexistent interface */ /* non-local address */ /* clear address */ /* clear interface */ /* sendmsg() sin6_scope differs with ancillary data interface */ }
void add_sock_input(nmsgtool_ctx *c, const char *ss) { char *t; int pa, pz, pn, pl; t = strchr(ss, '/'); if (t == NULL) usage("argument to -l needs a /"); if (sscanf(t + 1, "%d..%d", &pa, &pz) == 2) { if (pa > pz || pz - pa > 20) usage("bad port range in -l argument"); } else if (sscanf(t + 1, "%d", &pa) == 1) { pz = pa; } else { usage("need a port number or range after /"); } pl = t - ss; for (pn = pa; pn <= pz; pn++) { char *spec; int pf, s; nmsgtool_sockaddr su; nmsg_input_t input; nmsg_res res; nmsg_asprintf(&spec, "%*.*s/%d", pl, pl, ss, pn); pf = getsock(&su, spec, NULL, NULL); if (c->debug >= 2) fprintf(stderr, "%s: nmsg socket input: %s\n", argv_program, spec); free(spec); if (pf < 0) usage("bad -l socket"); s = socket(pf, SOCK_DGRAM, 0); if (s < 0) { perror("socket"); exit(1); } Setsockopt(s, SOL_SOCKET, SO_REUSEADDR, on); #ifdef SO_REUSEPORT Setsockopt(s, SOL_SOCKET, SO_REUSEPORT, on); #endif #ifdef __linux__ # ifdef SO_RCVBUFFORCE if (geteuid() == 0) { int rcvbuf = 16777216; if (setsockopt(s, SOL_SOCKET, SO_RCVBUFFORCE, &rcvbuf, sizeof(rcvbuf)) < 0) { if (c->debug >= 2) { fprintf(stderr, "%s: setsockopt(SO_RCVBUFFORCE) failed: %s\n", argv_program, strerror(errno)); } } } # endif #endif if (bind(s, &su.sa, NMSGTOOL_SA_LEN(su.sa)) < 0) { perror("bind"); exit(1); } input = nmsg_input_open_sock(s); if (input == NULL) { fprintf(stderr, "%s: nmsg_input_open_sock() failed\n", argv_program); exit(1); } setup_nmsg_input(c, input); res = nmsg_io_add_input(c->io, input, NULL); if (res != nmsg_res_success) { fprintf(stderr, "%s: nmsg_io_add_input() failed\n", argv_program); exit(1); } c->n_inputs += 1; } }
void add_sock_output(nmsgtool_ctx *c, const char *ss) { char *r, *t; int pa, pz, pn, pl; t = strchr(ss, '/'); r = strchr(ss, ','); if (t == NULL) usage("argument to -s needs a /"); if (sscanf(t + 1, "%d..%d", &pa, &pz) == 2) { if (pa > pz || pz - pa > 20) usage("bad port range in -s argument"); } else if (sscanf(t + 1, "%d", &pa) == 1) { pz = pa; } else { usage("need a port number or range after /"); } pl = t - ss; for (pn = pa; pn <= pz; pn++) { char *spec; int len, pf, s; nmsgtool_sockaddr su; nmsg_output_t output; nmsg_res res; unsigned rate = 0, freq = 0; nmsg_asprintf(&spec, "%*.*s/%d%s", pl, pl, ss, pn, r != NULL ? r : ""); pf = getsock(&su, spec, &rate, &freq); if (freq == 0) freq = DEFAULT_FREQ; if (c->debug >= 2) fprintf(stderr, "%s: nmsg socket output: %s\n", argv_program, spec); if (c->debug >= 2 && rate > 0) fprintf(stderr, "%s: nmsg socket rate: %u freq: %u\n", argv_program, rate, freq); free(spec); if (pf < 0) usage("bad -s socket"); s = socket(pf, SOCK_DGRAM, 0); if (s < 0) { perror("socket"); exit(1); } Setsockopt(s, SOL_SOCKET, SO_BROADCAST, on); len = 32 * 1024; Setsockopt(s, SOL_SOCKET, SO_SNDBUF, len); if (connect(s, &su.sa, NMSGTOOL_SA_LEN(su.sa)) < 0) { perror("connect"); exit(1); } output = nmsg_output_open_sock(s, c->mtu); if (output == NULL) { fprintf(stderr, "%s: nmsg_output_open_sock() failed\n", argv_program); exit(1); } setup_nmsg_output(c, output); if (rate > 0 && freq > 0) { nmsg_rate_t nr; nr = nmsg_rate_init(rate, freq); assert(nr != NULL); nmsg_output_set_rate(output, nr); } if (c->kicker != NULL) { res = nmsg_io_add_output(c->io, output, (void *) -1); } else { res = nmsg_io_add_output(c->io, output, NULL); } if (res != nmsg_res_success) { fprintf(stderr, "%s: nmsg_io_add_output() failed\n", argv_program); exit(1); } c->n_outputs += 1; } }
/* this only handles CHAT requests, otherwise it's handled in filesys */ static int filesys_DCC_CHAT(char *nick, char *from, char *handle, char *object, char *keyword, char *text) { char *param, *ip, *prt, buf[512], *msg = buf; int i, sock; struct userrec *u = get_user_by_handle(userlist, handle); struct flag_record fr = {FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0}; Context; if (!strncasecmp(text, "SEND ", 5)) { filesys_dcc_send(nick, from, u, text + 5); return 1; } if (strncasecmp(text, "CHAT ", 5) || !u) return 0; strcpy(buf, text + 5); get_user_flagrec(u, &fr, 0); param = newsplit(&msg); if (dcc_total == max_dcc) { putlog(LOG_MISC, "*", DCC_TOOMANYDCCS2, "CHAT(file)", param, nick, from); } else if (glob_party(fr) || (!require_p && chan_op(fr))) return 0; /* allow ctcp.so to pick up the chat */ else if (!glob_xfer(fr)) { if (!quiet_reject) dprintf(DP_HELP, "NOTICE %s :.\n", nick, DCC_REFUSED3); putlog(LOG_MISC, "*", "%s: %s!%s", DCC_REFUSED, nick, from); } else if (u_pass_match(u, "-")) { if (!quiet_reject) dprintf(DP_HELP, "NOTICE %s :%s.\n", nick, DCC_REFUSED3); putlog(LOG_MISC, "*", "%s: %s!%s", DCC_REFUSED4, nick, from); } else if (!dccdir[0]) { putlog(LOG_MISC, "*", "%s: %s!%s", DCC_REFUSED5, nick, from); } else { ip = newsplit(&msg); prt = newsplit(&msg); sock = getsock(0); if (open_telnet_dcc(sock, ip, prt) < 0) { neterror(buf); if (!quiet_reject) dprintf(DP_HELP, "NOTICE %s :%s (%s)\n", nick, DCC_CONNECTFAILED1, buf); putlog(LOG_MISC, "*", "%s: CHAT(file) (%s!%s)", DCC_CONNECTFAILED2, nick, from); putlog(LOG_MISC, "*", " (%s)", buf); killsock(sock); } else if ((atoi(prt) < min_dcc_port) || (atoi(prt) > max_dcc_port)) { /* invalid port range, do clients even use over 5000?? */ if (!quiet_reject) dprintf(DP_HELP, "NOTICE %s :%s (invalid port)\n", nick, DCC_CONNECTFAILED1); putlog(LOG_FILES, "*", "%s: %s!%s", DCC_REFUSED7, nick, from); } else { i = new_dcc(&DCC_FILES_PASS, sizeof(struct file_info)); dcc[i].addr = my_atoul(ip); dcc[i].port = atoi(prt); dcc[i].sock = sock; strcpy(dcc[i].nick, u->handle); strcpy(dcc[i].host, from); dcc[i].status = STAT_ECHO; dcc[i].timeval = now; dcc[i].u.file->chat = get_data_ptr(sizeof(struct chat_info)); bzero(dcc[i].u.file->chat, sizeof(struct chat_info)); strcpy(dcc[i].u.file->chat->con_chan, "*"); dcc[i].user = u; putlog(LOG_MISC, "*", "DCC connection: CHAT(file) (%s!%s)", nick, from); dprintf(i, "%s\n", DCC_ENTERPASS); } } return 1; }
/* received a ctcp-dcc */ static void filesys_dcc_send(char *nick, char *from, struct userrec *u, char *text) { char *param, *ip, *prt, buf[512], s1[512], *msg = buf; FILE *f; int atr = u ? u->flags : 0, i, j; Context; strcpy(buf, text); param = newsplit(&msg); if (!(atr & USER_XFER)) { putlog(LOG_FILES, "*", "Refused DCC SEND %s (no access): %s!%s", param, nick, from); } else if (!dccin[0] && !upload_to_cd) { dprintf(DP_HELP, "NOTICE %s :DCC file transfers not supported.\n", nick); putlog(LOG_FILES, "*", "Refused dcc send %s from %s!%s", param, nick, from); } else if (strchr(param, '/')) { dprintf(DP_HELP, "NOTICE %s :Filename cannot have '/' in it...\n", nick); putlog(LOG_FILES, "*", "Refused dcc send %s from %s!%s", param, nick, from); } else { ip = newsplit(&msg); prt = newsplit(&msg); if ((atoi(prt) < min_dcc_port) || (atoi(prt) > max_dcc_port)) { /* invalid port range, do clients even use over 5000?? */ dprintf(DP_HELP, "NOTICE %s :%s (invalid port)\n", nick, DCC_CONNECTFAILED1); putlog(LOG_FILES, "*", "Refused dcc send %s (%s): invalid port", param, nick); } else if (atoi(msg) == 0) { dprintf(DP_HELP, "NOTICE %s :Sorry, file size info must be included.\n", nick); putlog(LOG_FILES, "*", "Refused dcc send %s (%s): no file size", param, nick); } else if (atoi(msg) > (dcc_maxsize * 1024)) { dprintf(DP_HELP, "NOTICE %s :Sorry, file too large.\n", nick); putlog(LOG_FILES, "*", "Refused dcc send %s (%s): file too large", param, nick); } else { /* This looks like a good place for a sanity check. */ if (!sanitycheck_dcc(nick, from, ip, prt)) return; i = new_dcc(&DCC_FORK_SEND, sizeof(struct xfer_info)); if (i < 0) { dprintf(DP_HELP, "NOTICE %s :Sorry, too many DCC connections.\n", nick); putlog(LOG_MISC, "*", "DCC connections full: SEND %s (%s!%s)", param, nick, from); } dcc[i].addr = my_atoul(ip); dcc[i].port = atoi(prt); dcc[i].sock = -1; strcpy(dcc[i].nick, nick); strcpy(dcc[i].host, from); if (param[0] == '.') param[0] = '_'; strncpy(dcc[i].u.xfer->filename, param, 120); dcc[i].u.xfer->filename[120] = 0; if (upload_to_cd) { char *p = get_user(&USERENTRY_DCCDIR, u); if (p) sprintf(dcc[i].u.xfer->dir, "%s%s/", dccdir, p); else sprintf(dcc[i].u.xfer->dir, "%s", dccdir); } else strcpy(dcc[i].u.xfer->dir, dccin); dcc[i].u.xfer->length = atoi(msg); sprintf(s1, "%s%s", dcc[i].u.xfer->dir, param); Context; f = fopen(s1, "r"); if (f) { fclose(f); dprintf(DP_HELP, "NOTICE %s :That file already exists.\n", nick); lostdcc(i); } else { /* check for dcc-sends in process with the same filename */ for (j = 0; j < dcc_total; j++) if (j != i) { if ((dcc[j].type->flags & (DCT_FILETRAN | DCT_FILESEND)) == (DCT_FILETRAN | DCT_FILESEND)) { if (!strcmp(param, dcc[j].u.xfer->filename)) { dprintf(DP_HELP, "NOTICE %s :That file is already being sent.\n", nick); lostdcc(i); return; } } } /* put uploads in /tmp first */ sprintf(s1, "%s%s", tempdir, param); dcc[i].u.xfer->f = fopen(s1, "w"); if (dcc[i].u.xfer->f == NULL) { dprintf(DP_HELP, "NOTICE %s :Can't create that file (temp dir error)\n", nick); lostdcc(i); } else { dcc[i].timeval = now; dcc[i].sock = getsock(SOCK_BINARY); if (open_telnet_dcc(dcc[i].sock, ip, prt) < 0) { dcc[i].type->eof(i); } } } } } }
int recvit(struct proc *p, int s, struct msghdr *mp, caddr_t namelenp, register_t *retsize) { struct file *fp; struct uio auio; struct iovec *iov; int i; size_t len; int error; struct mbuf *from = NULL, *control = NULL; #ifdef KTRACE struct iovec *ktriov = NULL; #endif if ((error = getsock(p->p_fd, s, &fp)) != 0) return (error); auio.uio_iov = mp->msg_iov; auio.uio_iovcnt = mp->msg_iovlen; auio.uio_segflg = UIO_USERSPACE; auio.uio_rw = UIO_READ; auio.uio_procp = p; auio.uio_offset = 0; /* XXX */ auio.uio_resid = 0; iov = mp->msg_iov; for (i = 0; i < mp->msg_iovlen; i++, iov++) { /* Don't allow sum > SSIZE_MAX */ if (iov->iov_len > SSIZE_MAX || (auio.uio_resid += iov->iov_len) > SSIZE_MAX) { error = EINVAL; goto out; } } #ifdef KTRACE if (KTRPOINT(p, KTR_GENIO)) { int iovlen = auio.uio_iovcnt * sizeof (struct iovec); ktriov = malloc(iovlen, M_TEMP, M_WAITOK); bcopy(auio.uio_iov, ktriov, iovlen); } #endif len = auio.uio_resid; error = soreceive(fp->f_data, &from, &auio, NULL, mp->msg_control ? &control : NULL, &mp->msg_flags, mp->msg_control ? mp->msg_controllen : 0); if (error) { if (auio.uio_resid != len && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) error = 0; } #ifdef KTRACE if (ktriov != NULL) { if (error == 0) ktrgenio(p, s, UIO_READ, ktriov, len - auio.uio_resid); free(ktriov, M_TEMP); } #endif if (error) goto out; *retsize = len - auio.uio_resid; if (mp->msg_name) { socklen_t alen; if (from == NULL) alen = 0; else { alen = from->m_len; error = copyout(mtod(from, caddr_t), mp->msg_name, MIN(alen, mp->msg_namelen)); if (error) goto out; #ifdef KTRACE if (KTRPOINT(p, KTR_STRUCT)) ktrsockaddr(p, mtod(from, caddr_t), alen); #endif } mp->msg_namelen = alen; if (namelenp && (error = copyout(&alen, namelenp, sizeof(alen)))) { goto out; } } if (mp->msg_control) { len = mp->msg_controllen; if (len <= 0 || control == NULL) len = 0; else { struct mbuf *m = control; caddr_t p = mp->msg_control; do { i = m->m_len; if (len < i) { mp->msg_flags |= MSG_CTRUNC; i = len; } error = copyout(mtod(m, caddr_t), p, i); if (m->m_next) i = ALIGN(i); p += i; len -= i; if (error != 0 || len <= 0) break; } while ((m = m->m_next) != NULL); len = p - (caddr_t)mp->msg_control; } mp->msg_controllen = len; } if (!error) { fp->f_rxfer++; fp->f_rbytes += *retsize; } out: FRELE(fp, p); if (from) m_freem(from); if (control) m_freem(control); return (error); }
int handle_startup(int which, void * obj) { struct nebstruct_process_struct *ps = (struct nebstruct_process_struct *)obj; time_t now = ps->timestamp.tv_sec; switch(ps->type) { case NEBTYPE_PROCESS_START: if(daemon_mode && !sigrestart) return 0; case NEBTYPE_PROCESS_DAEMONIZE: { json_t * pubdef = NULL, *pulldef = NULL, *reqdef = NULL; int numthreads = 1; if(get_values(config, "iothreads", JSON_INTEGER, 0, &numthreads, "publish", JSON_OBJECT, 0, &pubdef, "pull", JSON_OBJECT, 0, &pulldef, "reply", JSON_OBJECT, 0, &reqdef, NULL) != 0) { syslog(LOG_ERR, "Parameter error while starting NagMQ"); return -1; } if(!pubdef && !pulldef && !reqdef) return 0; zmq_ctx = zmq_init(numthreads); if(zmq_ctx == NULL) { syslog(LOG_ERR, "Error initialzing ZMQ: %s", zmq_strerror(errno)); return -1; } if(pubdef && handle_pubstartup(pubdef) < 0) return -1; if(pulldef) { unsigned long interval = 2; get_values(pulldef, "interval", JSON_INTEGER, 0, &interval, NULL); if((pullsock = getsock("pull", ZMQ_PULL, pulldef)) == NULL) return -1; schedule_new_event(EVENT_USER_FUNCTION, 1, now, 1, interval, NULL, 1, input_reaper, pullsock, 0); } if(reqdef) { unsigned long interval = 2; get_values(reqdef, "interval", JSON_INTEGER, 0, &interval, NULL); if((reqsock = getsock("reply", ZMQ_REP, reqdef)) == NULL) return -1; schedule_new_event(EVENT_USER_FUNCTION, 1, now, 1, interval, NULL, 1, input_reaper, reqsock, 0); } if(pulldef || reqdef) neb_register_callback(NEBCALLBACK_TIMED_EVENT_DATA, handle, 0, handle_timedevent); break; } case NEBTYPE_PROCESS_SHUTDOWN: case NEBTYPE_PROCESS_RESTART: if(pullsock) zmq_close(pullsock); if(reqsock) zmq_close(reqsock); if(pubext) zmq_close(pubext); zmq_term(zmq_ctx); break; case NEBTYPE_PROCESS_EVENTLOOPSTART: case NEBTYPE_PROCESS_EVENTLOOPEND: if(pubext) { struct payload * payload; payload = payload_new(); switch(ps->type) { case NEBTYPE_PROCESS_EVENTLOOPSTART: payload_new_string(payload, "type", "eventloopstart"); break; case NEBTYPE_PROCESS_EVENTLOOPEND: payload_new_string(payload, "type", "eventloopend"); break; } payload_new_timestamp(payload, "timestamp", &ps->timestamp); payload_finalize(payload); process_payload(payload); } break; } return 0; }