int main(int argc, char *argv[]) { int keep_going = 1; int reload_config = 1; int i; struct rtmon_t _rtmon; /*int selfpipe = selfpipe_init();*/ memset(&_options, 0, sizeof(_options)); if (rtmon_init(&_rtmon, proc_route)) { err(1,"netlink"); } for (i=1; i < argc; i++) { if (strcmp(argv[i], "-debug")==0) { debug = 1; } else if (strcmp(argv[i], "-file")==0) { chilli_conf = argv[i+1]; } else if (strcmp(argv[i], "-pid")==0) { chilli_pid = atoi(argv[i+1]); } } _options.foreground = debug; _options.debug = debug; log_dbg("running"); chilli_signals(&keep_going, &reload_config); rtmon_discover_ifaces(&_rtmon); rtmon_discover_routes(&_rtmon); if (debug) { rtmon_print_ifaces(&_rtmon, 1); rtmon_print_routes(&_rtmon, 1); } rtmon_check_updates(&_rtmon); while (keep_going) { /* select */ /* check selfpipe */ rtmon_read_event(&_rtmon); } /* selfpipe_finish();*/ return 0; }
int main(int argc, char **argv) { int status; int idx; int active_last = 0; int active = 0; struct redir_t *redir; int keep_going = 1; int reload_config = 0; uint8_t hwaddr[6]; struct ifreq ifr; int selfpipe; int fd = socket(AF_INET, SOCK_DGRAM, 0); options_init(); chilli_signals(&keep_going, &reload_config); process_options(argc, argv, 1); safe_strncpy(ifr.ifr_name, _options.dhcpif, sizeof(ifr.ifr_name)); #ifdef SIOCGIFHWADDR if (ioctl(fd, SIOCGIFHWADDR, (caddr_t)&ifr) == 0) { memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, PKT_ETH_ALEN); } else { log_err(errno, "could not get MAC address"); return -1; } #endif close(fd); /* create an instance of redir */ if (redir_new(&redir, &_options.uamlisten, _options.uamport, #ifdef ENABLE_UAMUIPORT _options.uamuiport #else 0 #endif )) { log_err(0, "Failed to create redir"); return -1; } if (redir_listen(redir)) { log_err(0, "Failed to create redir listen"); return -1; } redir_set(redir, hwaddr, (_options.debug)); redir_set_cb_getstate(redir, sock_redir_getstate); redir->cb_handle_url = redir_handle_url; if (net_select_init(&sctx)) log_err(errno, "select init"); selfpipe = selfpipe_init(); /* epoll */ net_select_addfd(&sctx, selfpipe, SELECT_READ); net_select_addfd(&sctx, redir->fd[0], SELECT_READ); net_select_addfd(&sctx, redir->fd[1], SELECT_READ); if (_options.gid && setgid(_options.gid)) { log_err(errno, "setgid(%d) failed while running with gid = %d\n", _options.gid, getgid()); } if (_options.uid && setuid(_options.uid)) { log_err(errno, "setuid(%d) failed while running with uid = %d\n", _options.uid, getuid()); } while (keep_going) { /* select/poll */ net_select_zero(&sctx); net_select_fd(&sctx, selfpipe, SELECT_READ); net_select_fd(&sctx, redir->fd[0], SELECT_READ); net_select_fd(&sctx, redir->fd[1], SELECT_READ); active = 0; if (reload_config) { reload_options(argc, argv); reload_config = 0; redir_set(redir, hwaddr, _options.debug); } for (idx=0; idx < max_requests; idx++) { conn_select_fd(&requests[idx].conn, &sctx); if (requests[idx].inuse && requests[idx].socket_fd) { time_t now = mainclock_tick(); int fd = requests[idx].socket_fd; int timeout = 60; if (now - requests[idx].last_active > timeout) { log_dbg("timeout connection %d", idx); redir_conn_finish(&requests[idx].conn, &requests[idx]); } else { int evt = SELECT_READ; timeout = 0; if (conn_write_remaining(&requests[idx].conn)) evt |= SELECT_WRITE; net_select_fd(&sctx, fd, evt); active++; } #if(_debug_ > 1) if (_options.debug) { struct sockaddr_in address; socklen_t addrlen = sizeof(address); if (getpeername(fd, (struct sockaddr *)&address, &addrlen) >= 0) { char line[512]; safe_snprintf(line, sizeof(line), "#%d (%d) %d connection from %s %d", timeout ? -1 : active, fd, (int) requests[idx].last_active, inet_ntoa(address.sin_addr), ntohs(address.sin_port)); if (requests[idx].conn.sock) { addrlen = sizeof(address); if (getpeername(requests[idx].conn.sock, (struct sockaddr *)&address, &addrlen) >= 0) { safe_snprintf(line+strlen(line), sizeof(line)-strlen(line), " to %s %d", inet_ntoa(address.sin_addr), ntohs(address.sin_port)); } } if (timeout) { safe_snprintf(line+strlen(line), sizeof(line)-strlen(line), " (timeout)"); } log_dbg("%s", line); } } #endif } } if (active != active_last) { log_dbg("active connections: %d", active); active_last = active; } status = net_select(&sctx); #if defined(USING_POLL) && defined(HAVE_SYS_EPOLL_H) && (_debug_ > 1) if (_options.debug && status > 0) { int i; log_dbg("epoll %d", status); for (i=0; i < status; i++) { log_dbg("epoll fd %d %d", sctx.events[i].data.fd, sctx.events[i].events); } } #endif switch (status) { case -1: log_err(errno, "select() returned -1!"); break; default: if (status > 0) { if (net_select_read_fd(&sctx, selfpipe)==1) { chilli_handle_signal(0, 0); } if (redir->fd[0]) if (net_select_read_fd(&sctx, redir->fd[0])==1 && redir_accept2(redir, 0) < 0) log_err(0, "redir_accept() failed!"); if (redir->fd[1]) if (net_select_read_fd(&sctx, redir->fd[1])==1 && redir_accept2(redir, 1) < 0) log_err(0, "redir_accept() failed!"); for (idx=0; idx < max_requests; idx++) { /* * Update remote connections with activity */ conn_select_update(&requests[idx].conn, &sctx); /* * Check client connections with activity */ if (requests[idx].inuse && requests[idx].socket_fd) { int fd = requests[idx].socket_fd; #ifdef HAVE_SSL if (requests[idx].sslcon) { if (openssl_check_accept(requests[idx].sslcon, 0) < 0) { log_dbg("ssl error %d", errno); redir_conn_finish(&requests[idx].conn, &requests[idx]); continue; } } #endif switch (net_select_write_fd(&sctx, fd)) { case 1: log_dbg("client writeable"); redir_cli_rewrite(&requests[idx], &requests[idx].conn); break; } switch (net_select_read_fd(&sctx, fd)) { case -1: log_dbg("EXCEPTION"); redir_conn_finish(&requests[idx].conn, &requests[idx]); break; case 1: { if (requests[idx].proxy) { char b[PKT_MAX_LEN]; int r; #ifdef HAVE_SSL if (requests[idx].sslcon) { /* log_dbg("proxy_read_ssl"); */ r = openssl_read(requests[idx].sslcon, b, sizeof(b)-1, 0); } else #endif r = safe_read(fd, b, sizeof(b)-1); /* log_dbg("proxy_read: %d %d", fd, r); */ if (r <= 0) { log_dbg("recv %d %d %d", r, requests[idx].conn.read_buf->slen - requests[idx].conn.read_pos, errno); if (!(r == -1 && (errno == EWOULDBLOCK || errno == EAGAIN))) { if (redir_cli_rewrite(&requests[idx], &requests[idx].conn) == 0) { log_dbg("done reading and writing"); redir_conn_finish(&requests[idx].conn, &requests[idx]); } } } else if (r > 0) { int w; requests[idx].last_active = mainclock_tick(); w = net_write(requests[idx].conn.sock, b, r); /* log_dbg("proxy_write: %d", w); */ if (r != w) { log_err(errno, "problem writing what we read from client"); redir_conn_finish(&requests[idx].conn, &requests[idx]); } } } else { #ifdef HAVE_SSL go_again: #endif switch (redir_main(redir, fd, fd, &requests[idx].conn.peer, &requests[idx].baddr, requests[idx].uiidx, &requests[idx])) { case 1: /*log_dbg("redir cont'ed");*/ #ifdef HAVE_SSL if (requests[idx].sslcon && openssl_pending(requests[idx].sslcon) > 0) { log_dbg("ssl_pending, trying again"); goto go_again; } #endif break; case -1: log_dbg("redir error"); default: log_dbg("redir completed"); redir_conn_finish(&requests[idx].conn, &requests[idx]); break; } } } break; } } } } break; } } redir_free(redir); child_killall(SIGKILL); selfpipe_finish(); return 0; }
int main(int argc, char **argv) { struct radius_packet_t radius_pack; struct in_addr radiuslisten; struct timeval timeout; int maxfd = 0; fd_set fdread; fd_set fdwrite; fd_set fdexcep; ssize_t status; int keep_going = 1; int reload_config = 1; int selfpipe; options_init(); selfpipe = selfpipe_init(); chilli_signals(&keep_going, &reload_config); process_options(argc, argv, 1); radiuslisten.s_addr = htonl(INADDR_ANY); memset(&server, 0, sizeof(server)); if (!(server.env = initssl_cli())) { syslog(LOG_ERR, "Failed to create ssl environment"); return -1; } if (radius_new(&server.radius_auth, &radiuslisten, _options.radiusauthport ? _options.radiusauthport : RADIUS_AUTHPORT, 0, 0)) { syslog(LOG_ERR, "Failed to create radius"); return -1; } if (radius_new(&server.radius_acct, &radiuslisten, _options.radiusacctport ? _options.radiusacctport : RADIUS_ACCTPORT, 0, 0)) { syslog(LOG_ERR, "Failed to create radius"); return -1; } if (_options.coaport) { if (radius_new(&server.radius_cli, &radiuslisten, 0, 0, 0) || radius_init_q(server.radius_cli, 8)) { syslog(LOG_ERR, "Failed to create radius"); return -1; } radius_set(server.radius_cli, 0, 0); radius_set_cb_auth_conf(server.radius_cli, cb_radius_auth_conf); } radius_set(server.radius_auth, 0, 0); radius_set(server.radius_acct, 0, 0); if (_options.gid && setgid(_options.gid)) { syslog(LOG_ERR, "%d setgid(%d) failed while running with gid = %d\n", errno, _options.gid, getgid()); } if (_options.uid && setuid(_options.uid)) { syslog(LOG_ERR, "%d setuid(%d) failed while running with uid = %d\n", errno, _options.uid, getuid()); } while (keep_going) { if (reload_config) { reload_options(argc, argv); reload_config = 0; } FD_ZERO(&fdread); FD_ZERO(&fdwrite); FD_ZERO(&fdexcep); FD_SET(selfpipe, &fdread); FD_SET(server.radius_auth->fd, &fdread); FD_SET(server.radius_acct->fd, &fdread); if (server.radius_auth->fd > maxfd) maxfd = server.radius_auth->fd; if (server.radius_acct->fd > maxfd) maxfd = server.radius_acct->fd; if (server.conn.sock) { FD_SET(server.conn.sock, &fdread); if (server.conn.sock > maxfd) maxfd = server.conn.sock; } if (server.radius_cli) { FD_SET(server.radius_cli->fd, &fdread); if (server.radius_cli->fd > maxfd) maxfd = server.radius_cli->fd; } timeout.tv_sec = 1; timeout.tv_usec = 0; status = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout); switch (status) { case -1: if (errno != EINTR) syslog(LOG_ERR, "%s: select() returned -1!", strerror(errno)); break; case 0: default: if (status > 0) { struct sockaddr_in addr; socklen_t fromlen = sizeof(addr); if (FD_ISSET(selfpipe, &fdread)) { chilli_handle_signal(0, 0); } if (FD_ISSET(server.radius_auth->fd, &fdread)) { /* * ---> Authentication */ if ((status = recvfrom(server.radius_auth->fd, &radius_pack, sizeof(radius_pack), 0, (struct sockaddr *) &addr, &fromlen)) <= 0) { syslog(LOG_ERR, "%s: recvfrom() failed", strerror(errno)); return -1; } memcpy(&server.auth_peer, &addr, sizeof(addr)); process_radius(&radius_pack, status); } if (FD_ISSET(server.radius_acct->fd, &fdread)) { /* * ---> Accounting */ syslog(LOG_DEBUG, "received accounting"); if ((status = recvfrom(server.radius_acct->fd, &radius_pack, sizeof(radius_pack), 0, (struct sockaddr *) &addr, &fromlen)) <= 0) { syslog(LOG_ERR, "%s: recvfrom() failed", strerror(errno)); return -1; } memcpy(&server.acct_peer, &addr, sizeof(addr)); process_radius(&radius_pack, status); } if (server.radius_cli) { if (FD_ISSET(server.radius_cli->fd, &fdread)) { radius_decaps(server.radius_cli, 0); } } if (server.conn.sock) { if (FD_ISSET(server.conn.sock, &fdread)) { process_radius_reply(); } } } break; } } selfpipe_finish(); return 0; }