// sleeps msec or until net socket is ready void NET_Sleep(int msec) { struct timeval timeout; fd_set fdset; extern cvar_t *dedicated; // >>> FIX: For Nintendo Wii using devkitPPC / libogc // This does not exist in the platform. Removing: //extern qboolean stdin_active; // <<< FIX if (!ip_sockets[NS_SERVER] || (dedicated && !dedicated->value)) return; // we're not a server, just run full speed FD_ZERO(&fdset); // >>> FIX: For Nintendo Wii using devkitPPC / libogc // This does not exist in the platform. Removing: //if (stdin_active) // FD_SET(0, &fdset); // stdin is processed too // <<< FIX FD_SET(ip_sockets[NS_SERVER], &fdset); // network socket timeout.tv_sec = msec/1000; timeout.tv_usec = (msec%1000)*1000; // >>> FIX: For Nintendo Wii using devkitPPC / libogc // Switching to the equivalent function in the platform: //select(ip_sockets[NS_SERVER]+1, &fdset, NULL, NULL, &timeout); net_select(ip_sockets[NS_SERVER]+1, &fdset, NULL, NULL, &timeout); // <<< FIX }
void net_run() { while(true) { net_select(); net_clean(); Sleep(10); } }
static s32 tcp_connect(char *host, const u16 port) { struct hostent *hp; struct sockaddr_in sa; fd_set myset; struct timeval tv; s32 s, res; s = tcp_socket(); if (s < 0) return s; memset(&sa, 0, sizeof(struct sockaddr_in)); sa.sin_family= PF_INET; sa.sin_len = sizeof(struct sockaddr_in); sa.sin_port= htons(port); #ifdef HW_RVL hp = net_gethostbyname (host); if (!hp || !(hp->h_addrtype == PF_INET)) { return errno; } memcpy((char *) &sa.sin_addr, hp->h_addr_list[0], hp->h_length); #endif #ifdef HW_DOL u32 addr = inet_addr("205.205.224.54"); memcpy(&sa.sin_addr, (struct in_addr*)&addr, sizeof(struct in_addr)); #endif res = net_connect (s, (struct sockaddr *) &sa, sizeof (sa)); if (res == EINPROGRESS) { tv.tv_sec = TCP_CONNECT_TIMEOUT; tv.tv_usec = 0; FD_ZERO(&myset); FD_SET(s, &myset); if (net_select(s+1, NULL, &myset, NULL, &tv) <= 0) return -1; } return s; }
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; }
static void main_event_loop(void) { net_select(1); }
void CheckForNetworkEvents(int server_socket, int client_socket, std::vector<FifoFrameData>& frames, std::vector<AnalyzedFrameInfo>& analyzed_frames) { #if 0 fd_set readset; FD_ZERO(&readset); // FD_SET(server_socket, &readset); // if (client_socket != -1) FD_SET(client_socket, &readset); // int maxfd = std::max(client_socket, server_socket); int maxfd = client_socket; struct timeval timeout; timeout.tv_sec = 1; timeout.tv_usec = 0; char data[12]; int ret = net_select(maxfd+1, &readset, NULL, NULL, &timeout); // TODO: Is this compatible with winsocks? if (ret <= 0) { if (ret < 0) printf("select returned %d\n", ret); return; } /* if (FD_ISSET(server_socket, &readset)) { int new_socket = net_accept(server_socket, NULL, NULL); if (new_socket < 0) { qDebug() << "accept failed"; } else client_socket = new_socket; }*/ #endif struct pollsd fds[2]; memset(fds, 0, sizeof(fds)); // fds[0].socket = server_socket; fds[0].socket = client_socket; fds[0].events = POLLIN; int nfds = 1; int timeout = 1; // TODO: Set to zero int ret; do { ret = net_poll(fds, nfds, timeout); if (ret < 0) { printf("poll returned error %d\n", ret); return; } if (ret == 0) { printf("timeout :(\n"); // timeout return; } char cmd; ssize_t numread = net_recv(client_socket, &cmd, 1, 0); printf("Peeked command %d\n", cmd); switch (cmd) { case CMD_HANDSHAKE: if (RET_SUCCESS == ReadHandshake(client_socket)) printf("Successfully exchanged handshake token!\n"); else printf("Failed to exchange handshake token!\n"); // TODO: should probably write a handshake in return, but ... I'm lazy break; case CMD_STREAM_DFF: //ReadStreamedDff(client_socket); break; case CMD_ENABLE_COMMAND: case CMD_DISABLE_COMMAND: ReadCommandEnable(client_socket, analyzed_frames, (cmd == CMD_ENABLE_COMMAND) ? true : false); break; case CMD_PATCH_COMMAND: ReadCommandPatch(client_socket, frames); break; default: printf("Received unknown command: %d\n", cmd); break; } printf("Looping again\n"); timeout = 100; } while (ret > 0); }