/** * This is the main message reading loop. Messages are read, validated, * decrypted if necessary, then passed to the appropriate routine for handling. */ void mainloop() { struct uftp_h *header; unsigned char *buf, *decrypted, *message; int packetlen, listidx, hostidx, i; unsigned int decryptlen, meslen; uint8_t *func; struct sockaddr_in src; struct in_addr srcaddr; struct timeval *tv; const int bsize = 9000; // Roughly size of ethernet jumbo frame log0(0, 0, "%s", VERSIONSTR); for (i = 0; i < key_count; i++) { log(0, 0, "Loaded key with fingerprint %s", print_key_fingerprint(privkey[i])); } buf = calloc(bsize, 1); decrypted = calloc(bsize, 1); if ((buf == NULL) || (decrypted == NULL)) { syserror(0, 0, "calloc failed!"); exit(1); } header = (struct uftp_h *)buf; while (1) { tv = getrecenttimeout(); if (read_packet(listener, &src, buf, &packetlen, bsize, tv) <= 0) { continue; } if ((header->uftp_id != UFTP_VER_NUM) && (header->uftp_id != UFTP_3_0_VER)) { log(0, 0, "Invalid message from %s: not uftp packet " "or invalid version", inet_ntoa(src.sin_addr)); continue; } if (packetlen != sizeof(struct uftp_h) + ntohs(header->blsize)) { log(0, 0, "Invalid packet size from %s: got %d, expected %d", inet_ntoa(src.sin_addr), packetlen, sizeof(struct uftp_h) + ntohs(header->blsize)); continue; } if ((src.sin_addr.s_addr == out_addr.s_addr) && (src.sin_port == htons(port))) { // Packet from self -- drop continue; } if (header->func == HB_REQ) { handle_hb_request(&src, buf); continue; } if (header->func == HB_RESP) { handle_hb_response(listener, &src, buf, hb_hosts, hbhost_count, noname, privkey[0]); continue; } if (header->func == KEY_REQ) { handle_key_req(&src, buf); continue; } if (header->func == PROXY_KEY) { // Only clients handle these, so drop continue; } if ((proxy_type == SERVER_PROXY) && (down_addr.sin_addr.s_addr == INADDR_ANY)) { log(0, 0, "Rejecting message from %s: downstream address " "not established", inet_ntoa(src.sin_addr)); continue; } listidx = find_group(ntohl(header->group_id)); if (header->func == ANNOUNCE) { handle_announce(listidx, &src, buf); } else { if (listidx == -1) { continue; } if (proxy_type == SERVER_PROXY) { // Server proxies don't do anything outside of an ANNOUNCE. // Just send it on through. forward_message(listidx, &src, buf); continue; } if (header->func == ABORT) { handle_abort(listidx, &src, buf); continue; } if (!memcmp(&src, &group_list[listidx].up_addr, sizeof(src))) { // Downstream message if (header->func == KEYINFO) { handle_keyinfo(listidx, buf); } else if ((header->func == REG_CONF) && (group_list[listidx].keytype != KEY_NONE)) { handle_regconf(listidx, buf); } else { // If we don't need to process the message, don't bother // decrypting anything. Just forward it on. forward_message(listidx, &src, buf); } } else { // Upstream message // Decrypt first if necessary hostidx = find_client(listidx, header->srcaddr); if ((hostidx != -1) && (header->func == ENCRYPTED) && (group_list[listidx].keytype != KEY_NONE)) { if (!validate_and_decrypt(buf, &decrypted, &decryptlen, group_list[listidx].mtu,group_list[listidx].keytype, group_list[listidx].groupkey, group_list[listidx].groupsalt, group_list[listidx].ivlen, group_list[listidx].hashtype, group_list[listidx].grouphmackey, group_list[listidx].hmaclen, group_list[listidx].sigtype, group_list[listidx].destinfo[hostidx].pubkey, group_list[listidx].destinfo[hostidx].pubkeylen)) { log(ntohl(header->group_id), 0, "Rejecting message " "from %s: decrypt/validate failed", inet_ntoa(src.sin_addr)); continue; } func = (uint8_t *)decrypted; message = decrypted; meslen = decryptlen; } else { if ((hostidx != -1) && (group_list[listidx].keytype != KEY_NONE) && ((header->func == INFO_ACK) || (header->func == STATUS) || (header->func == COMPLETE))) { log(ntohl(header->group_id), 0, "Rejecting %s message " "from %s: not encrypted", func_name(header->func), inet_ntoa(src.sin_addr)); continue; } func = (uint8_t *)&header->func; message = buf + sizeof(struct uftp_h); meslen = ntohs(header->blsize); } if ((hostidx == -1) && (header->srcaddr == 0)) { srcaddr = src.sin_addr; } else { srcaddr.s_addr = header->srcaddr; } switch (*func) { case REGISTER: handle_register(listidx, hostidx, message, meslen, srcaddr.s_addr); break; case CLIENT_KEY: handle_clientkey(listidx, hostidx, message, meslen, srcaddr.s_addr); break; case INFO_ACK: handle_info_ack(listidx, hostidx, message, meslen); break; case STATUS: handle_status(listidx, hostidx, message, meslen); break; case COMPLETE: handle_complete(listidx, hostidx, message, meslen); break; default: forward_message(listidx, &src, buf); break; } } } } }
void network_thread () { /* * We loop forever waiting on either data from the ppp drivers or from * our network socket. Control handling is no longer done here. */ int fromlen; /* Length of the address */ int tunnel, call; /* Tunnel and call */ int recvsize; /* Length of data received */ struct buffer *buf; /* Payload buffer */ struct call *c, *sc; /* Call to send this off to */ struct tunnel *st; /* Tunnel */ fd_set readfds; /* Descriptors to watch for reading */ int max; /* Highest fd */ struct timeval tv; /* Timeout for select */ /* This one buffer can be recycled for everything except control packets */ buf = new_buf (MAX_RECV_SIZE); gconfig.debug_tunnel = 1; for (;;) { max = build_fdset (&readfds); tv.tv_sec = 1; tv.tv_usec = 0; schedule_unlock (); select (max + 1, &readfds, NULL, NULL, NULL); schedule_lock (); if (FD_ISSET (control_fd, &readfds)) { do_control (); } if (FD_ISSET (server_socket, &readfds)) { /* * Okay, now we're ready for reading and processing new data. */ recycle_buf (buf); /* Reserve space for expanding payload packet headers */ buf->start += PAYLOAD_BUF; buf->len -= PAYLOAD_BUF; fromlen = sizeof (from); recvsize = recvfrom (server_socket, buf->start, buf->len, 0, (struct sockaddr *) &from, &fromlen); if (recvsize < MIN_PAYLOAD_HDR_LEN) { if (recvsize < 0) { if (errno != EAGAIN) log (LOG_WARN, "%s: recvfrom returned error %d (%s)\n", __FUNCTION__, errno, strerror (errno)); } else { log (LOG_WARN, "%s: received too small a packet\n", __FUNCTION__); } } else { buf->len = recvsize; if (gconfig.debug_network) { log (LOG_DEBUG, "%s: recv packet from %s, size = %d, " "tunnel = %d, call = %d\n", __FUNCTION__, inet_ntoa (from.sin_addr), recvsize, tunnel, call); } if (gconfig.packet_dump) { do_packet_dump (buf); } fix_hdr (buf->start); extract (buf->start, &tunnel, &call); if (! (c = get_call (tunnel, call, from.sin_addr.s_addr, from.sin_port))) { log(LOG_DEBUG, "%s(%d)\n", __FUNCTION__,__LINE__); if ((c = get_tunnel (tunnel, from.sin_addr.s_addr, from.sin_port))) { /* * It is theoretically possible that we could be sent * a control message (say a StopCCN) on a call that we * have already closed or some such nonsense. To prevent * this from closing the tunnel, if we get a call on a valid * tunnel, but not with a valid CID, we'll just send a ZLB * to ack receiving the packet. */ if (gconfig.debug_tunnel) log (LOG_DEBUG, "%s: no such call %d on tunnel %d. Sending special ZLB\n", __FUNCTION__); handle_special (buf, c, call); } else log (LOG_DEBUG, "%s: unable to find call or tunnel to handle packet. call = %d, tunnel = %d Dumping.\n", __FUNCTION__, call, tunnel); } else { buf->peer = from; /* Handle the packet */ c->container->chal_us.vector = NULL; if (handle_packet (buf, c->container, c)) { if (gconfig.debug_tunnel) log (LOG_DEBUG, "%s(%d): bad packet\n", __FUNCTION__,__LINE__); }; if (c->cnu) { /* Send Zero Byte Packet */ control_zlb (buf, c->container, c); c->cnu = 0; } } } }; st = tunnels.head; while (st) { sc = st->call_head; while (sc) { if ((sc->fd >= 0) && FD_ISSET (sc->fd, &readfds)) { /* Got some payload to send */ int result; recycle_payload (buf, sc->container->peer); #ifdef DEBUG_FLOW_MORE log (LOG_DEBUG, "%s: rws = %d, pSs = %d, pLr = %d\n", __FUNCTION__, sc->rws, sc->pSs, sc->pLr); #endif /* if ((sc->rws>0) && (sc->pSs > sc->pLr + sc->rws) && !sc->rbit) { #ifdef DEBUG_FLOW log(LOG_DEBUG, "%s: throttling payload (call = %d, tunnel = %d, Lr = %d, Ss = %d, rws = %d)!\n",__FUNCTION__, sc->cid, sc->container->tid, sc->pLr, sc->pSs, sc->rws); #endif sc->throttle = -1; We unthrottle in handle_packet if we get a payload packet, valid or ZLB, but we also schedule a dethrottle in which case the R-bit will be set FIXME: Rate Adaptive timeout? tv.tv_sec = 2; tv.tv_usec = 0; sc->dethrottle = schedule(tv, dethrottle, sc); } else */ /* while ((result=read_packet(buf,sc->fd,sc->frame & SYNC_FRAMING))>0) { */ while ((result = read_packet (buf, sc->fd, SYNC_FRAMING)) > 0) { add_payload_hdr (sc->container, sc, buf); if (gconfig.packet_dump) { do_packet_dump (buf); } sc->prx = sc->data_rec_seq_num; if (sc->zlb_xmit) { deschedule (sc->zlb_xmit); sc->zlb_xmit = NULL; } sc->tx_bytes += buf->len; sc->tx_pkts++; udp_xmit (buf); recycle_payload (buf, sc->container->peer); } if (result != 0) { log (LOG_WARN, "%s: tossing read packet, error = %s (%d). Closing call.\n", __FUNCTION__, strerror (-result), -result); strcpy (sc->errormsg, strerror (-result)); sc->needclose = -1; } } sc = sc->next; } st = st->next; } } }
int main(int argc, char *argv[]) { int listenfd, connfd; int ret; struct sockaddr_in client_addr, server_addr; socklen_t clilen; char buf[BUFLEN]; packet *pac, *pac_ret; #if !GLIB_CHECK_VERSION(2, 36, 0) g_type_init(); #endif #ifdef WIN32 WSADATA wsadata; WSAStartup(0x0101, &wsadata); #endif start_rpc_service(); listenfd = socket(AF_INET, SOCK_STREAM, 0); if (listenfd < 0) { fprintf(stderr, "socket failed: %s\n", strerror(errno)); exit(-1); } int on = 1; if (setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) < 0) { fprintf (stderr, "setsockopt of SO_REUSEADDR error: %s\n", strerror(errno)); exit(-1); } memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(12345); ret = bind(listenfd, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (ret < 0) { fprintf(stderr, "bind failed: %s\n", strerror(errno)); exit(-1); } ret = listen(listenfd, 5); if (ret < 0) { fprintf(stderr, "listen failed: %s\n", strerror(errno)); exit(-1); } while (1) { GError *error = NULL; clilen = sizeof(client_addr); connfd = accept(listenfd, (struct sockaddr *)&client_addr, &clilen); if (connfd < 0) { fprintf(stderr, "accept failed: %s\n", strerror(errno)); continue; } /* read the header packet */ pac = read_packet(connfd, buf); if (pac == NULL) { fprintf(stderr, "read packet failed: %s\n", strerror(errno)); exit(-1); } gsize ret_len; int fcall_len = ntohs(pac->length); /* Execute the RPC function */ char *res = searpc_server_call_function ("searpc-demo", pac->data, fcall_len, &ret_len); pac_ret = (packet *)buf; pac_ret->length = htons((uint16_t)ret_len); memcpy(pac_ret->data, res, ret_len); /* send the ret packet */ if (writen (connfd, buf, PACKET_HEADER_LENGTH + ret_len) == -1) { fprintf (stderr, "write packet failed: %s\n", strerror(errno)); exit(-1); } } return 0; }
void decode_encode_big(struct Type* t) { char *buf; char buf2[2048]; void *p; /* (TYPE*) */ int size1 = 0; int size2 = 0; int size3 = 0; int err, index = 0, len, type; ei_x_buff arg; MESSAGE("ei_decode_%s, arg is type %s", t->name, t->type); buf = read_packet(NULL); ei_get_type(buf+1, &index, &type, &len); p = ei_alloc_big(len); err = t->ei_decode_fp(buf+1, &size1, p); if (err != 0) { if (err != -1) { fail("decode returned non zero but not -1"); } else { fail("decode returned non zero"); } return; } if (size1 < 1) { fail("size is < 1"); return; } MESSAGE("ei_encode_%s buf is NULL, arg is type %s", t->name, t->type); err = t->ei_encode_fp(NULL, &size2, p); if (err != 0) { if (err != -1) { fail("size calculation returned non zero but not -1"); return; } else { fail("size calculation returned non zero"); return; } } if (size1 != size2) { MESSAGE("size1 = %d, size2 = %d\n",size1,size2); fail("decode and encode size differs when buf is NULL"); return; } MESSAGE("ei_encode_%s, arg is type %s", t->name, t->type); err = t->ei_encode_fp(buf2, &size3, p); if (err != 0) { if (err != -1) { fail("returned non zero but not -1"); } else { fail("returned non zero"); } return; } if (size1 != size3) { MESSAGE("size1 = %d, size2 = %d\n",size1,size3); fail("decode and encode size differs"); return; } send_buffer(buf2, size1); MESSAGE("ei_x_encode_%s, arg is type %s", t->name, t->type); ei_x_new(&arg); err = t->ei_x_encode_fp(&arg, p); if (err != 0) { if (err != -1) { fail("returned non zero but not -1"); } else { fail("returned non zero"); } ei_x_free(&arg); return; } if (arg.index < 1) { fail("size is < 1"); ei_x_free(&arg); return; } send_buffer(arg.buff, arg.index); ei_x_free(&arg); ei_free_big(p); free_packet(buf); }
void session_loop(void(*loophandler)()) { fd_set readfd, writefd; struct timeval timeout; int val; /* main loop, select()s for all sockets in use */ for(;;) { const int writequeue_has_space = (ses.writequeue_len <= 2*TRANS_MAX_PAYLOAD_LEN); timeout.tv_sec = select_timeout(); timeout.tv_usec = 0; FD_ZERO(&writefd); FD_ZERO(&readfd); dropbear_assert(ses.payload == NULL); /* We delay reading from the input socket during initial setup until after we have written out our initial KEXINIT packet (empty writequeue). This means our initial packet can be in-flight while we're doing a blocking read for the remote ident. We also avoid reading from the socket if the writequeue is full, that avoids replies backing up */ if (ses.sock_in != -1 && (ses.remoteident || isempty(&ses.writequeue)) && writequeue_has_space) { FD_SET(ses.sock_in, &readfd); } if (ses.sock_out != -1 && !isempty(&ses.writequeue)) { FD_SET(ses.sock_out, &writefd); } /* We get woken up when signal handlers write to this pipe. SIGCHLD in svr-chansession is the only one currently. */ FD_SET(ses.signal_pipe[0], &readfd); /* set up for channels which can be read/written */ setchannelfds(&readfd, &writefd, writequeue_has_space); /* Pending connections to test */ set_connect_fds(&writefd); val = select(ses.maxfd+1, &readfd, &writefd, NULL, &timeout); if (exitflag) { dropbear_exit("Terminated by signal"); } if (val < 0 && errno != EINTR) { dropbear_exit("Error in select"); } if (val <= 0) { /* If we were interrupted or the select timed out, we still * want to iterate over channels etc for reading, to handle * server processes exiting etc. * We don't want to read/write FDs. */ FD_ZERO(&writefd); FD_ZERO(&readfd); } /* We'll just empty out the pipe if required. We don't do any thing with the data, since the pipe's purpose is purely to wake up the select() above. */ if (FD_ISSET(ses.signal_pipe[0], &readfd)) { char x; while (read(ses.signal_pipe[0], &x, 1) > 0) {} } /* check for auth timeout, rekeying required etc */ checktimeouts(); /* process session socket's incoming data */ if (ses.sock_in != -1) { if (FD_ISSET(ses.sock_in, &readfd)) { if (!ses.remoteident) { /* blocking read of the version string */ read_session_identification(); } else { read_packet(); } } /* Process the decrypted packet. After this, the read buffer * will be ready for a new packet */ if (ses.payload != NULL) { process_packet(); } } /* if required, flush out any queued reply packets that were being held up during a KEX */ maybe_flush_reply_queue(); handle_connect_fds(&writefd); /* process pipes etc for the channels, ses.dataallowed == 0 * during rekeying ) */ channelio(&readfd, &writefd); /* process session socket's outgoing data */ if (ses.sock_out != -1) { if (!isempty(&ses.writequeue)) { write_packet(); } } if (loophandler) { loophandler(); } } /* for(;;) */ /* Not reached */ }
/** * Perform the Announce/Register phase for a particular group/file * Group & encryption: ->ANNOUNCE <-REGISTER ->KEYINFO <-INFO_ACK * Group & no encryption: ->ANNOUNCE <-REGISTER ->REG_CONF * Files within a group: ->FILEINFO <-INFO_ACK * If client_key == 1, REGISTER is followed by CLIENT_KEY * Returns 1 if at least one client responded, 0 if none responded */ int announce_phase(struct finfo_t *finfo) { time_t endtime; int attempt, resend, announce, regconf, keyinfo, fileinfo, open, anyerror; int len, rval, rcv_status, last_pass, gotall, gotone, allreg, regdone, i; unsigned char *packet, *decrypted; struct uftp_h *header; struct timeval timeout; struct sockaddr_in receiver; if (finfo->file_id) { log1(0, 0, "File ID: %04X Name: %s", finfo->file_id, finfo->filename); log1(0, 0, " sending as: %s", finfo->destfname); switch (finfo->ftype) { case FTYPE_REG: log(0, 0, "Bytes: %s Blocks: %d Sections: %d", printll(finfo->size), finfo->blocks, finfo->sections); break; case FTYPE_DIR: log(0, 0, "Empty directory"); break; case FTYPE_LINK: log(0, 0, "Symbolic link to %s", finfo->linkname); break; } } else { log(0, 0, "Initializing group"); if (sync_mode) { log0(0, 0, "- Connect -"); } } rval = 1; packet = calloc(mtu, 1); decrypted = calloc(mtu, 1); if ((packet == NULL) || (decrypted == NULL)) { syserror(0, 0, "calloc failed!"); exit(1); } header = (struct uftp_h *)packet; endtime = time(NULL) + announce_time; announce = (finfo->file_id == 0); regconf = (announce && (keytype == KEY_NONE)); keyinfo = (announce && (keytype != KEY_NONE)); fileinfo = (finfo->file_id != 0); open = (destcount == 0); for (i = 0; i < destcount; i++) { // At start of group, initialize all clients/proxies to DEST_MUTE. // At start of file, initialize proxies to DEST_ACTIVE (since they // don't respond directly to a FILEINFO) and clients to DEST_REGISTERED. if (announce) { destlist[i].status = DEST_MUTE; } else if (!client_error(i)) { if (destlist[i].clientcnt != -1) { destlist[i].status = DEST_ACTIVE; } else { destlist[i].status = DEST_REGISTERED; } } } timeout.tv_sec = announce_int / 1000; timeout.tv_usec = (announce_int % 1000) * 1000; resend = 1; attempt = 1; last_pass = 0; regdone = 0; while (time(NULL) < endtime) { // On the initial pass, or when the announce timeout trips, // send any necessary messages. if (resend) { if (keyinfo && !send_keyinfo(finfo, attempt)) { continue; } if (announce && !send_regconf(finfo, attempt, regconf)) { continue; } if (fileinfo && !send_fileinfo(finfo, attempt)) { continue; } if (announce && !send_announce(finfo, attempt, open)) { continue; } resend = 0; } // TODO: Currently, the interval between sends is really an inactivity // timer, not the actual time between sends. We might want to change // it to that, and perhaps add an extra "overage" timer in case we're // still processing responses when we're due to resend, that way we'll // always wait some minimum amount of time. if ((rcv_status = read_packet(sock, &receiver, packet, &len, mtu, &timeout)) == -1) { continue; } else if (rcv_status == 0) { attempt++; resend = 1; if (last_pass) break; continue; } if (!validate_packet(packet, len, finfo)) { continue; } if (!handle_announce_phase(packet, decrypted, &receiver, finfo, announce, open, regconf)) { continue; } if (!open) { for (i = 0, gotall = 1, allreg = 1; (i < destcount) && (gotall || allreg); i++) { if (announce) { gotall = gotall && ((destlist[i].status == DEST_ACTIVE) || (destlist[i].status == DEST_ABORT)); allreg = allreg && ((destlist[i].status == DEST_ACTIVE) || (destlist[i].status == DEST_REGISTERED) || (destlist[i].status == DEST_ABORT)); } else { gotall = gotall && ((destlist[i].status == DEST_ACTIVE) || (destlist[i].status == DEST_DONE) || (client_error(i))); } } if (gotall) { // Break out right away if this is a file registration. // For group registration, do one last wait, even if // encryption is enabled since we can still send a // REG_CONF for a client behind a proxy. // Change the wait interval to the client's register_int * 1.5 // to allow for late registers. // Be careful not to overrun the phase timeout! if (finfo->file_id != 0) break; timeout.tv_sec = (int)(register_int / 1000 * 1.5); timeout.tv_usec = (int)((register_int % 1000) * 1000 * 1.5); if (timeout.tv_sec > endtime) { #ifdef WINDOWS timeout.tv_sec = (long)endtime; #else timeout.tv_sec = endtime; #endif timeout.tv_usec = 0; } if (!last_pass) { log(0, 0, "Late registers:"); } last_pass = 1; send_regconf(finfo, attempt + 1, regconf); } else if (announce && allreg && !regdone) { // All have registered, so don't wait to send the next message resend = 1; regdone = 1; } } } for (i = 0, gotone = 0, anyerror = 0; i < destcount; i++) { gotone = gotone || (((destlist[i].status == DEST_ACTIVE) || (destlist[i].status == DEST_DONE)) && (destlist[i].clientcnt == -1)); if (destlist[i].status == DEST_REGISTERED) { log1(0, 0, "Couldn't get INFO_ACK from %s", destlist[i].name); destlist[i].status = DEST_LOST; anyerror = 1; } if ((destlist[i].status == DEST_MUTE) || (destlist[i].status == DEST_ABORT)) { anyerror = 1; } } if (anyerror && quit_on_error) { log0(0, 0, "Aboring all clients"); send_abort(finfo, "A client dropped out, aborting all", &receive_dest, NULL, (keytype != KEY_NONE), 0); for (i = 0; i < destcount; i++) { if (destlist[i].status == DEST_ACTIVE) { destlist[i].status = DEST_ABORT; } } rval = 0; } if (!gotone) { log0(0, 0, "Announce timed out"); rval = 0; } if (open) { send_regconf(finfo, attempt, regconf); } if ((finfo->file_id == 0) && sync_mode) { for (i = 0; i < destcount; i++) { if (destlist[i].status == DEST_ACTIVE) { log0(0, 0, "CONNECT;success;%s", destlist[i].name); } else { log0(0, 0, "CONNECT;failed;%s", destlist[i].name); } } log0(0, 0, "- Transfer -"); } free(packet); free(decrypted); return rval; }
int main(int argc, char *argv[]) { enum { FD_SOCKET, FD_WALL_TIMER, FD_NOLOGIN_TIMER, FD_SHUTDOWN_TIMER, _FD_MAX }; int r = EXIT_FAILURE, n_fds; int one = 1; struct shutdownd_command c; struct pollfd pollfd[_FD_MAX]; bool exec_shutdown = false, unlink_nologin = false, failed = false; unsigned i; if (getppid() != 1) { log_error("This program should be invoked by init only."); return EXIT_FAILURE; } if (argc > 1) { log_error("This program does not take arguments."); return EXIT_FAILURE; } log_set_target(LOG_TARGET_SYSLOG_OR_KMSG); log_parse_environment(); log_open(); if ((n_fds = sd_listen_fds(true)) < 0) { log_error("Failed to read listening file descriptors from environment: %s", strerror(-r)); return EXIT_FAILURE; } if (n_fds != 1) { log_error("Need exactly one file descriptor."); return EXIT_FAILURE; } if (setsockopt(SD_LISTEN_FDS_START, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0) { log_error("SO_PASSCRED failed: %m"); return EXIT_FAILURE; } zero(c); zero(pollfd); pollfd[FD_SOCKET].fd = SD_LISTEN_FDS_START; pollfd[FD_SOCKET].events = POLLIN; for (i = 0; i < _FD_MAX; i++) { if (i == FD_SOCKET) continue; pollfd[i].events = POLLIN; if ((pollfd[i].fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC)) < 0) { log_error("timerfd_create(): %m"); failed = true; } } if (failed) goto finish; log_debug("systemd-shutdownd running as pid %lu", (unsigned long) getpid()); sd_notify(false, "READY=1\n" "STATUS=Processing requests..."); do { int k; usec_t n; if (poll(pollfd, _FD_MAX, -1) < 0) { if (errno == EAGAIN || errno == EINTR) continue; log_error("poll(): %m"); goto finish; } n = now(CLOCK_REALTIME); if (pollfd[FD_SOCKET].revents) { if ((k = read_packet(pollfd[FD_SOCKET].fd, &c)) < 0) goto finish; else if (k > 0 && c.elapse > 0) { struct itimerspec its; char date[FORMAT_TIMESTAMP_MAX]; if (c.warn_wall) { /* Send wall messages every so often */ zero(its); timespec_store(&its.it_value, when_wall(n, c.elapse)); if (timerfd_settime(pollfd[FD_WALL_TIMER].fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) { log_error("timerfd_settime(): %m"); goto finish; } /* Warn immediately if less than 15 minutes are left */ if (n < c.elapse && n + 15*USEC_PER_MINUTE >= c.elapse) warn_wall(n, &c); } /* Disallow logins 5 minutes prior to shutdown */ zero(its); timespec_store(&its.it_value, when_nologin(c.elapse)); if (timerfd_settime(pollfd[FD_NOLOGIN_TIMER].fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) { log_error("timerfd_settime(): %m"); goto finish; } /* Shutdown after the specified time is reached */ zero(its); timespec_store(&its.it_value, c.elapse); if (timerfd_settime(pollfd[FD_SHUTDOWN_TIMER].fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) { log_error("timerfd_settime(): %m"); goto finish; } sd_notifyf(false, "STATUS=Shutting down at %s...", format_timestamp(date, sizeof(date), c.elapse)); } } if (pollfd[FD_WALL_TIMER].revents) { struct itimerspec its; warn_wall(n, &c); flush_fd(pollfd[FD_WALL_TIMER].fd); /* Restart timer */ zero(its); timespec_store(&its.it_value, when_wall(n, c.elapse)); if (timerfd_settime(pollfd[FD_WALL_TIMER].fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) { log_error("timerfd_settime(): %m"); goto finish; } } if (pollfd[FD_NOLOGIN_TIMER].revents) { int e; log_info("Creating /run/nologin, blocking further logins..."); if ((e = write_one_line_file("/run/nologin", "System is going down.")) < 0) log_error("Failed to create /run/nologin: %s", strerror(-e)); else unlink_nologin = true; flush_fd(pollfd[FD_NOLOGIN_TIMER].fd); } if (pollfd[FD_SHUTDOWN_TIMER].revents) { exec_shutdown = true; goto finish; } } while (c.elapse > 0); r = EXIT_SUCCESS; log_debug("systemd-shutdownd stopped as pid %lu", (unsigned long) getpid()); finish: for (i = 0; i < _FD_MAX; i++) if (pollfd[i].fd >= 0) close_nointr_nofail(pollfd[i].fd); if (unlink_nologin) unlink("/run/nologin"); if (exec_shutdown) { char sw[3]; sw[0] = '-'; sw[1] = c.mode; sw[2] = 0; execl(SYSTEMCTL_BINARY_PATH, "shutdown", sw, "now", (c.warn_wall && c.wall_message[0]) ? c.wall_message : (c.warn_wall ? NULL : "--no-wall"), NULL); log_error("Failed to execute /sbin/shutdown: %m"); } sd_notify(false, "STATUS=Exiting..."); return r; }
bool FeMedia::onGetData( Chunk &data ) { int offset=0; data.samples = NULL; data.sampleCount = 0; if ( (!m_audio) || end_of_file() ) return false; while ( offset < m_audio->codec_ctx->sample_rate ) { AVPacket *packet = m_audio->pop_packet(); while (( packet == NULL ) && ( !end_of_file() )) { read_packet(); packet = m_audio->pop_packet(); } if ( packet == NULL ) { m_audio->at_end=true; if ( offset > 0 ) return true; return false; } #if (LIBAVCODEC_VERSION_INT < AV_VERSION_INT( 53, 25, 0 )) { sf::Lock l( m_audio->buffer_mutex ); int bsize = MAX_AUDIO_FRAME_SIZE; if ( avcodec_decode_audio3( m_audio->codec_ctx, (m_audio->buffer + offset), &bsize, packet) < 0 ) { std::cerr << "Error decoding audio." << std::endl; FeBaseStream::free_packet( packet ); return false; } else { offset += bsize / sizeof( sf::Int16 ); data.sampleCount += bsize / sizeof(sf::Int16); data.samples = m_audio->buffer; } } #else #if (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT( 55, 45, 0 )) AVFrame *frame = av_frame_alloc(); m_audio->codec_ctx->refcounted_frames = 1; #else AVFrame *frame = avcodec_alloc_frame(); #endif // // TODO: avcodec_decode_audio4() can return multiple frames per packet depending on the codec. // We don't deal with this appropriately... // int got_frame( 0 ); int len = avcodec_decode_audio4( m_audio->codec_ctx, frame, &got_frame, packet ); if ( len < 0 ) { #ifdef FE_DEBUG char buff[256]; av_strerror( len, buff, 256 ); std::cerr << "Error decoding audio: " << buff << std::endl; #endif } if ( got_frame ) { int data_size = av_samples_get_buffer_size( NULL, m_audio->codec_ctx->channels, frame->nb_samples, m_audio->codec_ctx->sample_fmt, 1); #ifdef DO_RESAMPLE if ( m_audio->codec_ctx->sample_fmt == AV_SAMPLE_FMT_S16 ) #endif { sf::Lock l( m_audio->buffer_mutex ); memcpy( (m_audio->buffer + offset), frame->data[0], data_size ); offset += data_size / sizeof( sf::Int16 ); data.sampleCount += data_size / sizeof(sf::Int16); data.samples = m_audio->buffer; } #ifdef DO_RESAMPLE else { sf::Lock l( m_audio->buffer_mutex ); if ( !m_audio->resample_ctx ) { m_audio->resample_ctx = resample_alloc(); if ( !m_audio->resample_ctx ) { std::cerr << "Error allocating audio format converter." << std::endl; FeBaseStream::free_packet( packet ); FeBaseStream::free_frame( frame ); return false; } int64_t channel_layout = frame->channel_layout; if ( !channel_layout ) { channel_layout = av_get_default_channel_layout( m_audio->codec_ctx->channels ); } av_opt_set_int( m_audio->resample_ctx, "in_channel_layout", channel_layout, 0 ); av_opt_set_int( m_audio->resample_ctx, "in_sample_fmt", frame->format, 0 ); av_opt_set_int( m_audio->resample_ctx, "in_sample_rate", frame->sample_rate, 0 ); av_opt_set_int( m_audio->resample_ctx, "out_channel_layout", channel_layout, 0 ); av_opt_set_int( m_audio->resample_ctx, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0 ); av_opt_set_int( m_audio->resample_ctx, "out_sample_rate", frame->sample_rate, 0 ); #ifdef FE_DEBUG std::cout << "Initializing resampler: in_sample_fmt=" << av_get_sample_fmt_name( (AVSampleFormat)frame->format ) << ", in_sample_rate=" << frame->sample_rate << ", out_sample_fmt=" << av_get_sample_fmt_name( AV_SAMPLE_FMT_S16 ) << ", out_sample_rate=" << frame->sample_rate << std::endl; #endif if ( resample_init( m_audio->resample_ctx ) < 0 ) { std::cerr << "Error initializing audio format converter, input format=" << av_get_sample_fmt_name( (AVSampleFormat)frame->format ) << ", input sample rate=" << frame->sample_rate << std::endl; FeBaseStream::free_packet( packet ); FeBaseStream::free_frame( frame ); resample_free( &m_audio->resample_ctx ); m_audio->resample_ctx = NULL; return false; } } if ( m_audio->resample_ctx ) { int out_linesize; av_samples_get_buffer_size( &out_linesize, m_audio->codec_ctx->channels, frame->nb_samples, AV_SAMPLE_FMT_S16, 0 ); uint8_t *tmp_ptr = (uint8_t *)(m_audio->buffer + offset); #ifdef USE_SWRESAMPLE int out_samples = swr_convert( m_audio->resample_ctx, &tmp_ptr, frame->nb_samples, (const uint8_t **)frame->data, frame->nb_samples ); #else // USE_AVRESAMPLE int out_samples = avresample_convert( m_audio->resample_ctx, &tmp_ptr, out_linesize, frame->nb_samples, frame->data, frame->linesize[0], frame->nb_samples ); #endif if ( out_samples < 0 ) { std::cerr << "Error performing audio conversion." << std::endl; FeBaseStream::free_packet( packet ); FeBaseStream::free_frame( frame ); break; } offset += out_samples * m_audio->codec_ctx->channels; data.sampleCount += out_samples * m_audio->codec_ctx->channels; data.samples = m_audio->buffer; } } #endif } FeBaseStream::free_frame( frame ); #endif FeBaseStream::free_packet( packet ); } return true; }
int main(int argc, char *argv[]) { //memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32); if (argc < 6) { printf("usage %s ip port client_id(of friend to find ip_port of) filename(of file to send) client_id(ours)\n", argv[0]); exit(0); } addfriend(argv[3]); IP_Port friend_ip; int connection = -1; int inconnection = -1; //initialize networking //bind to ip 0.0.0.0:PORT IP ip; ip.i = 0; init_networking(ip, PORT); memcpy(self_client_id, argv[5], 32); perror("Initialization"); IP_Port bootstrap_ip_port; bootstrap_ip_port.port = htons(atoi(argv[2])); bootstrap_ip_port.ip.i = inet_addr(argv[1]); bootstrap(bootstrap_ip_port); IP_Port ip_port; char data[MAX_UDP_PACKET_SIZE]; uint32_t length; char buffer1[128]; int read1 = 0; char buffer2[128]; int read2 = 0; FILE *file1 = fopen(argv[4], "rb"); if ( file1==NULL ){printf("Error opening file.\n");return 1;} FILE *file2 = fopen("received.txt", "wb"); if ( file2==NULL ){return 1;} read1 = fread(buffer1, 1, 128, file1); while(1) { while(recievepacket(&ip_port, data, &length) != -1) { if(rand() % 3 != 1)//simulate packet loss { if(DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port)) { //if packet is not recognized printf("Received unhandled packet with length: %u\n", length); } else { printf("Received handled packet with length: %u\n", length); } } } friend_ip = getfriendip(argv[3]); if(friend_ip.ip.i != 0) { if(connection == -1) { printf("Started connecting to friend:"); printip(friend_ip); connection = new_connection(friend_ip); } } if(inconnection == -1) { inconnection = incoming_connection(); if(inconnection != -1) { printf("Someone connected to us:"); printip(connection_ip(inconnection)); } } //if someone connected to us write what he sends to a file //also send him our file. if(inconnection != -1) { if(write_packet(inconnection, buffer1, read1)) { printf("Wrote data.\n"); read1 = fread(buffer1, 1, 128, file1); } read2 = read_packet(inconnection, buffer2); if(read2 != 0) { printf("Received data.\n"); if(!fwrite(buffer2, read2, 1, file2)) { printf("file write error\n"); } if(read2 < 128) { fclose(file2); } } } //if we are connected to a friend send him data from the file. //also put what he sends us in a file. if(is_connected(connection) == 3) { if(write_packet(0, buffer1, read1)) { printf("Wrote data.\n"); read1 = fread(buffer1, 1, 128, file1); } read2 = read_packet(0, buffer2); if(read2 != 0) { printf("Received data.\n"); if(!fwrite(buffer2, read2, 1, file2)) { printf("file write error\n"); } if(read2 < 128) { fclose(file2); } } } doDHT(); doLossless_UDP(); //print_clientlist(); //print_friendlist(); //c_sleep(300); c_sleep(1); } shutdown_networking(); return 0; }
/* * get_input - called when incoming data is available. */ static void get_input() { int len, i; u_char *p; u_short protocol; struct protent *protp; p = inpacket_buf; /* point to beginning of packet buffer */ len = read_packet(inpacket_buf); if (len < 0) return; if (len == 0) { etime = time((time_t *) NULL); minutes = (etime-stime)/60; syslog(LOG_NOTICE, "Modem hangup, connected for %d minutes", (minutes >1) ? minutes : 1); hungup = 1; lcp_lowerdown(0); /* serial link is no longer available */ link_terminated(0); return; } if (debug /*&& (debugflags & DBG_INPACKET)*/) log_packet(p, len, "rcvd ", LOG_DEBUG); if (len < PPP_HDRLEN) { MAINDEBUG((LOG_INFO, "io(): Received short packet.")); return; } p += 2; /* Skip address and control */ GETSHORT(protocol, p); len -= PPP_HDRLEN; /* * Toss all non-LCP packets unless LCP is OPEN. */ if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) { MAINDEBUG((LOG_INFO, "get_input: Received non-LCP packet when LCP not open.")); return; } /* * Until we get past the authentication phase, toss all packets * except LCP, LQR and authentication packets. */ if (phase <= PHASE_AUTHENTICATE && !(protocol == PPP_LCP || protocol == PPP_LQR || protocol == PPP_PAP || protocol == PPP_CHAP)) { MAINDEBUG((LOG_INFO, "get_input: discarding proto 0x%x in phase %d", protocol, phase)); return; } /* * Upcall the proper protocol input routine. */ for (i = 0; (protp = protocols[i]) != NULL; ++i) { if (protp->protocol == protocol && protp->enabled_flag) { (*protp->input)(0, p, len); return; } if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag && protp->datainput != NULL) { (*protp->datainput)(0, p, len); return; } } if (debug) syslog(LOG_WARNING, "Unsupported protocol (0x%x) received", protocol); lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN); }
static int cl_dev_xmit(struct netdev *nd,struct socket *sk) { int ret; struct mbuf mb_d,mb; int maxfd,flags=0; fd_set in; unsigned int nbytes; mb_d.mb_data = xmalloc(IP_MAXRECV); mb_d.mb_len = 0; if(mb_d.mb_data == NULL) goto bad; mb.mb_data = xmalloc(2000*sizeof(char)); mb.mb_len = 0; if(mb.mb_data == NULL) goto bad; FD_ZERO(&in); maxfd = (nd->sk->sk_fd > nd->nd_fd)? nd->sk->sk_fd:nd->nd_fd; while(1) { FD_SET(nd->nd_fd,&in); FD_SET(nd->sk->sk_fd,&in); ret = select(maxfd+1,&in,NULL,NULL,NULL); if(ret == -1 || errno == EINTR) continue; /* we got something from device */ if(FD_ISSET(nd->nd_fd,&in)) { mb_d.mb_len = recvfrom(nd->nd_fd,mb_d.mb_data,IP_MAXPACKET,0,NULL,NULL); if(mb_d.mb_len == -1) { perrx("etn_cli_recv:recv"); goto bad; } #ifdef USE_SSL ret = SSL_write(nd->sk->sk_ssl,mb_d.mb_data,mb_d.mb_len); if(ret < 0) { perrx("etn_cli_recv:send"); goto bad; } #else ret = write(nd->sk->sk_fd,mb_d.mb_data,mb_d.mb_len); if(ret == -1) { perrx("etn_cli_recv:send"); goto bad; } #endif } /* we got something from socket */ if(FD_ISSET(nd->sk->sk_fd,&in)) { /* printf("lol\n"); mb.mb_len = read(nd->sk->sk_fd,mb.mb_data,4096); printf("READ : %d\n",mb.mb_len); if(mb.mb_len == -1) { perrx("recv_sock_handler:recv"); goto bad; } */ if(read_packet(nd->sk,&mb,1514) <= 0) { perrx("read"); perrx("read_packet():"); exit(0); goto bad; } printf("READ : %d\n",mb.mb_len); nbytes = sendto(nd->nd_fd,mb.mb_data,mb.mb_len,0,NULL,0); if(nbytes == -1) { perrx("recv_sock_handler:sendto"); goto bad; } } } bad: if(mb_d.mb_data) free(mb.mb_data); exit(0); return -1; }
int main( int argc, char *argv[] ) { int i; char fn_inspeech[80], fn_outspeech[80]; FILE *fin, *fout; int numread, nsamp; float temp[MAXSF]; unsigned long frame_num; unsigned long total_frames; unsigned long fer_count; struct ENCODER_MEM encoder_memory; struct DECODER_MEM decoder_memory; struct PACKET packet; struct CONTROL control; int input_format; int output_format; #if USE_CALLOC float *in_speech; float *out_speech; #else float in_speech[FSIZE+LPCSIZE-FSIZE+LPCOFFSET]; float out_speech[FSIZE]; #endif memset(&encoder_memory, 0, sizeof(encoder_memory)); memset(&decoder_memory, 0, sizeof(decoder_memory)); memset(&packet, 0, sizeof(packet)); memset(&control, 0, sizeof(control)); #if USE_CALLOC alloc_mem_for_speech(&in_speech, &out_speech); #endif for(i = 0; i < argc; i++) fprintf(stdout, "%s ", argv[i]); fprintf(stdout, "\n"); parse_command_line(argc, argv, fn_inspeech, fn_outspeech, &control); initialize_encoder_and_decoder(&encoder_memory, &decoder_memory, &control); print_welcome_message(); /*** Init TTY/TDD Routines and Varibles ***/ if( tty_debug_flag ) tty_debug(); if( tty_option == TTY_NO_GAIN ) { fprintf(stdout," TTY OPTION = NO GAIN\n"); init_tty_enc( &tty_enc_char, &tty_enc_header, &tty_enc_baud_rate); init_tty_dec(); } else { tty_option = 0; fprintf(stdout," TTY OPTION = OFF\n"); } if( trans_fname != NULL ) { fprintf(stdout,"FER SIMULATOR ON: seed = %d\n",fer_sim_seed); } for(i = 0; i < LPCORDER; i++) packet.lsp[i] = packet.lpc[i] = 0; encoder_memory.frame_num = 0; frame_num = 0; fer_count = 0; if (control.decode_only == YES) { /* Input is a CELP file */ switch (control.celp_file_format) { case FORMAT_PACKET: open_binary_input_file(&fin, fn_inspeech); total_frames = GetNumFrames(fin, sizeof(short)*WORDS_PER_PACKET); input_format = FORMAT_PACKET; break; case FORMAT_QCP: open_qcp_input_file(&fin, fn_inspeech); total_frames = get_qcp_packet_count(); input_format = FORMAT_QCP; break; default: fprintf(stderr, "unsupported decode_only input format %d\n", control.celp_file_format); exit(-2); } } else { /* Input is an audio file */ open_binary_input_file(&fin, fn_inspeech); input_format = FORMAT_RAW_AUDIO; total_frames = GetNumFrames(fin, sizeof(short)*FSIZE); } if ((control.form_res_out == YES) || (control.target_after_out == YES) || (control.cb_out == YES) || (control.pitch_out == YES)) { /* Output is encoder state for debugging */ open_binary_output_file(&fout, fn_outspeech); output_format = FORMAT_DEBUG_OUTPUT; } else if (control.encode_only == YES) { /* Output is a CELP file */ switch (control.celp_file_format) { case FORMAT_PACKET: open_binary_output_file(&fout, fn_outspeech); output_format = FORMAT_PACKET; break; case FORMAT_QCP: open_qcp_output_file(&fout, fn_outspeech, total_frames); output_format = FORMAT_QCP; break; default: fprintf(stderr, "unsupported encode_only output format %d\n", control.celp_file_format); exit(-2); } } else { /* Output is an audio file */ open_binary_output_file(&fout, fn_outspeech); output_format = FORMAT_RAW_AUDIO; } if(control.decode_only == NO) { #if 0 if (read_samples(fin, in_speech, LPCSIZE-FSIZE+LPCOFFSET) !=LPCSIZE-FSIZE+LPCOFFSET) { printf("Not even enough samples for 1 frame!\n"); usage(&control); } #else for( i=0 ; i < LPCSIZE-FSIZE+LPCOFFSET ; i++ ) { in_speech[i] = 0; } #endif } /*----------------------------------------------- * Main Loop *------------------------------------------------*/ while( control.num_frames == UNLIMITED || frame_num < control.num_frames ) { fprintf(stderr,"Processing %lu of %lu FER = %.2f%%\r", frame_num, total_frames, 100.0*fer_count/(frame_num+1)); if (control.decode_only==NO) { nsamp = read_samples(fin, &in_speech[LPCSIZE-FSIZE+LPCOFFSET], FSIZE); if( nsamp <= 0 ) { break; } else if(nsamp < FSIZE) { for (i=nsamp; i<FSIZE; i++) { in_speech[LPCSIZE-FSIZE+LPCOFFSET+i]=0; } } encoder(in_speech, &packet, &control, &encoder_memory, out_speech); update_snr(ENCODER, in_speech, out_speech, &(control.snr)); } if (control.decode_only==YES) { if (input_format == FORMAT_QCP) { numread = read_qcp_packet(fin, packet.data, WORDS_PER_PACKET); if (numread == 0) break; } else { /* FORMAT_PACKET */ numread = read_packet(fin, packet.data, WORDS_PER_PACKET); if( numread != WORDS_PER_PACKET) { if(numread != 0) { fprintf(stderr, "%s: Wrong number of words read: %d\n", argv[0], numread); } break; } } } if(control.encode_only==NO) { if (control.output_encoder_speech==NO) { decoder(out_speech, &packet, &control, &decoder_memory); if( packet.data[0] == ERASURE ) { fer_count++; } if(control.decode_only==NO) { update_snr(DECODER, in_speech, out_speech, &(control.snr)); } } i = write_samples(fout,out_speech,FSIZE); } else { if( trans_fname != NULL ) { fer_sim( &(packet.data[0]) ); } if( packet.data[0] == ERASURE ) { fer_count++; } if (output_format == FORMAT_QCP) { i = write_qcp_packet(fout, packet.data, WORDS_PER_PACKET); } else { i = write_packet(fout, packet.data, WORDS_PER_PACKET); } } /***** Update in_speech buffer ***************/ for (i=0; i<LPCSIZE-FSIZE+LPCOFFSET; i++) { in_speech[i]=in_speech[i+FSIZE]; } frame_num++; encoder_memory.frame_num = frame_num; } /* end main while() */ if (output_format == FORMAT_QCP) { finish_qcp_output_file(fout); } fclose(fin); fclose(fout); if ((control.encode_only==NO)&&(control.decode_only==NO)) { compute_snr(&(control.snr), &control); } if( control.decode_only == NO ) { /* calculate the avg. rate for active speech for the entire file */ temp[0] = (encoder_memory.full_cnt + encoder_memory.full_force + encoder_memory.full_cnt_t + encoder_memory.full_force_t)*14.4+ (encoder_memory.half_cnt + encoder_memory.half_force + encoder_memory.half_cnt_t + encoder_memory.half_force_t)*7.2+ (encoder_memory.quarter_cnt + encoder_memory.quarter_cnt_t)*3.6; temp[0] /= (encoder_memory.total_speech_frames+ (STATWINDOW-encoder_memory.block_cnt)); if(control.reduced_rate_flag != 0) { printf("\n The target_snr_threshold at the end of the run was %f", encoder_memory.target_snr_thr); printf("\n The average rate for the entire file was %f",temp[0]); i = STATWINDOW-encoder_memory.block_cnt+encoder_memory.total_speech_frames; temp[1] = i; printf("\n The # of speech frames in the file is = %d",i); i = encoder_memory.full_cnt+encoder_memory.full_cnt_t; printf("\n The percent of frames at 14.4 is %f",100.0*i/temp[1]); i = encoder_memory.full_force+encoder_memory.full_force_t; printf("\n The percent of frames forced to 14.4 is %f",100.*i/temp[1]); i = encoder_memory.half_cnt+encoder_memory.half_cnt_t; printf("\n The percent of frames at 7.2 is %f",100.*i/temp[1]); i = encoder_memory.half_force+encoder_memory.half_force_t; printf("\n The percent of frames forced to 7.2 is %f",100.*i/temp[1]); i = encoder_memory.quarter_cnt+encoder_memory.quarter_cnt_t; printf("\n The percent of frames coded at 3.6 is %f\n",100.*i/temp[1]); } } if(control.encode_only == NO) print_erasure_count(); free_encoder_and_decoder(&encoder_memory, &decoder_memory); #if USE_CALLOC free((char*) in_speech); free((char*) out_speech); #endif print_farewell_message(); exit(0); }/* end of main() */
int read_volparams(void) { int vol_params_read = FALSE; si32 nbytes_char; si32 nelev; si32 nheights; si32 *radar_elevations; si32 *plane_heights; si32 packet_id; vol_params_t *vol_params; /* * read in a packet */ while (!vol_params_read) { if (read_packet(&packet_id) == CS_FAILURE) { return(CS_FAILURE); } /* * check for volume packet type */ if (packet_id == VOL_PARAMS_PACKET_CODE) { vol_params = (vol_params_t *) Glob->packet; umalloc_verify(); /* * decode the data from network byte order */ BE_to_array_32((ui32 *) &vol_params->mid_time, (ui32) sizeof(radtim_t)); nbytes_char = (si32) BE_to_si32((ui32) vol_params->radar.nbytes_char); BE_to_array_32((ui32 *) &vol_params->radar, (ui32) (sizeof(radar_params_t) - nbytes_char)); nbytes_char = (si32) BE_to_si32((ui32) vol_params->cart.nbytes_char); BE_to_array_32((ui32 *) &vol_params->cart, (ui32) (sizeof(cart_params_t) - nbytes_char)); vol_params->nfields = (si32) BE_to_si32((ui32) vol_params->nfields); umalloc_verify(); radar_elevations = (si32 *) ((char *) vol_params + sizeof(vol_params_t)); nelev = vol_params->radar.nelevations; BE_to_array_32((ui32 *) radar_elevations, (ui32) (nelev * sizeof(si32))); plane_heights = radar_elevations + nelev; nheights = vol_params->cart.nz * N_PLANE_HEIGHT_VALUES; umalloc_verify(); BE_to_array_32((ui32 *) plane_heights, (ui32) (nheights * sizeof(si32))); /* * place this data in shared memory */ umalloc_verify(); setup_volume(vol_params, radar_elevations, plane_heights); vol_params_read = TRUE; } /* if (packet_id == VOL_PARAMS_PACKET_CODE) */ } /* while (!vol_params_read) */ return(CS_SUCCESS); }
int reader_thread(void *p) { // loop reading from motes, writing to directory static int tcnt=0; DATAPACKET *dataPacket; // dtn api variables int ret; dtn_handle_t handle; dtn_reg_info_t reginfo; dtn_reg_id_t regid = DTN_REGID_NONE; dtn_bundle_spec_t bundle_spec; dtn_bundle_payload_t send_payload; dtn_bundle_id_t bundle_id; char demux[4096]; p = NULL; // open the ipc handle if (debug > 0) fprintf(stdout, "Opening connection to local DTN daemon\n"); int err = 0; if (api_IP_set) err = dtn_open_with_IP(api_IP,api_port,&handle); else err = dtn_open(&handle); if (err != DTN_SUCCESS) { fprintf(stderr, "fatal error opening dtn handle: %s\n", dtn_strerror(err)); exit(1); } // ---------------------------------------------------- // initialize bundle spec with src/dest/replyto // ---------------------------------------------------- // initialize bundle spec memset(&bundle_spec, 0, sizeof(bundle_spec)); // destination host is specified at run time, demux is hardcoded sprintf(demux, "%s/dtnmoteproxy/recv", arg_dest); parse_eid(handle, &bundle_spec.dest, demux); // source is local eid with file path as demux string sprintf(demux, "/dtnmoteproxy/send"); parse_eid(handle, &bundle_spec.source, demux); // reply to is the same as the source dtn_copy_eid(&bundle_spec.replyto, &bundle_spec.source); if (debug > 2) { print_eid("source_eid", &bundle_spec.source); print_eid("replyto_eid", &bundle_spec.replyto); print_eid("dest_eid", &bundle_spec.dest); } // set the return receipt option bundle_spec.dopts |= DOPTS_DELIVERY_RCPT; // send file and wait for reply // create a new dtn registration to receive bundle status reports memset(®info, 0, sizeof(reginfo)); dtn_copy_eid(®info.endpoint, &bundle_spec.replyto); reginfo.flags = DTN_REG_DEFER; reginfo.regid = regid; reginfo.expiration = 0; if ((ret = dtn_register(handle, ®info, ®id)) != 0) { fprintf(stderr, "error creating registration (id=%d): %d (%s)\n", regid, ret, dtn_strerror(dtn_errno(handle))); exit(1); } if (debug > 3) printf("dtn_register succeeded, regid 0x%x\n", regid); while (1) { static unsigned char motedata[BUFSIZ]; int length; int ret; if (debug > 1) fprintf(dout, "about to read from motes...\n"); while((ret=read_packet((char *) motedata, (int *) &length))) { if(ret==DEBUG_PKT) continue; if (debug > 0) { fprintf(dout, "\nreader loop... got [%d] bytes from motes\n", length); if (debug > 1) hexdump(motedata, length); } // the extra cast to void* is needed to circumvent gcc warnings // about unsafe casting dataPacket=(DATAPACKET *)((void*)motedata); // skip packets from base mote if(dataPacket->origin_mote_id == 0) continue; // set a default expiration time of one hour bundle_spec.expiration = 3600; // fill in a payload memset(&send_payload, 0, sizeof(send_payload)); dtn_set_payload(&send_payload, DTN_PAYLOAD_MEM, (char *) motedata, length); memset(&bundle_id, 0, sizeof(bundle_id)); if ((ret = dtn_send(handle, regid, &bundle_spec, &send_payload, &bundle_id)) != 0) { fprintf(stderr, "error sending bundle: %d (%s)\n", ret, dtn_strerror(dtn_errno(handle))); } else fprintf(stderr, "motedata bundle sent"); printf("Mote ID = %u\n",dataPacket->origin_mote_id); printf("Source Mote ID = %u\n",dataPacket->source_mote_id); printf("Hop Count = %u\n",dataPacket->hop_cnt); printf("Packet Type = %u\n",dataPacket->surge_pkt_type); printf("Parent Address = %u\n",dataPacket->surge_parent_addr); printf("Sequence Number = %u\n", (u_int)dataPacket->surge_seq_no); printf("Light = %u\n",dataPacket->light); printf("Temperature = %u\n\n",dataPacket->temp); tcnt=(tcnt+1)%10000; } if (debug > 0) fprintf(dout, "reader loop.... nothing to do? [shouldn't happen]\n"); } // if this was ever changed to gracefully shutdown, it would be good to call: dtn_close(handle); return (1); // NOTREACHED }
int gdbr_server_serve(libgdbr_t *g, gdbr_server_cmd_cb cmd_cb, void *core_ptr) { int ret; if (!g) { return -1; } while (1) { read_packet (g); if (g->data_len == 0) { continue; } if (r_str_startswith (g->data, "k")) { return _server_handle_k (g, cmd_cb, core_ptr); } if (r_str_startswith (g->data, "vKill")) { return _server_handle_vKill (g, cmd_cb, core_ptr); } if (r_str_startswith (g->data, "qSupported")) { if ((ret = _server_handle_qSupported (g)) < 0) { return ret; } continue; } if (r_str_startswith (g->data, "qTStatus")) { if ((ret = _server_handle_qTStatus (g)) < 0) { return ret; } continue; } if (r_str_startswith (g->data, "qC") && g->data_len == 2) { if ((ret = _server_handle_qC (g, cmd_cb, core_ptr)) < 0) { return ret; } continue; } if (r_str_startswith (g->data, "qAttached")) { if ((ret = _server_handle_qAttached (g, cmd_cb, core_ptr)) < 0) { return ret; } continue; } if (r_str_startswith (g->data, "vMustReplyEmpty")) { if ((ret = _server_handle_vMustReplyEmpty (g)) < 0) { return ret; } continue; } if (r_str_startswith (g->data, "qTfV")) { if ((ret = _server_handle_qTfV (g, cmd_cb, core_ptr)) < 0) { return ret; } continue; } if (r_str_startswith (g->data, "qfThreadInfo")) { if ((ret = _server_handle_qfThreadInfo (g, cmd_cb, core_ptr)) < 0) { return ret; } continue; } if (r_str_startswith (g->data, "qsThreadInfo")) { if ((ret = _server_handle_qsThreadInfo (g, cmd_cb, core_ptr)) < 0) { return ret; } continue; } if (r_str_startswith (g->data, "Hg")) { if ((ret = _server_handle_Hg (g, cmd_cb, core_ptr)) < 0) { return ret; } continue; } if (r_str_startswith (g->data, "Hc")) { if ((ret = _server_handle_Hc (g, cmd_cb, core_ptr)) < 0) { return ret; } continue; } if (r_str_startswith (g->data, "?")) { if ((ret = _server_handle_ques (g, cmd_cb, core_ptr)) < 0) { return ret; } continue; } if (r_str_startswith (g->data, "g") && g->data_len == 1) { if ((ret = _server_handle_g (g, cmd_cb, core_ptr)) < 0) { return ret; } continue; } if (r_str_startswith (g->data, "vCont")) { if ((ret = _server_handle_vCont (g, cmd_cb, core_ptr)) < 0) { return ret; } continue; } if (r_str_startswith (g->data, "qOffsets")) { if ((ret = _server_handle_qOffsets (g, cmd_cb, core_ptr)) < 0) { return ret; } continue; } if (g->data[0] == 'z' || g->data[0] == 'Z') { if ((ret = _server_handle_z (g, cmd_cb, core_ptr)) < 0) { return ret; } continue; } if (g->data[0] == 's') { if ((ret = _server_handle_s (g, cmd_cb, core_ptr)) < 0) { return ret; } continue; } if (g->data[0] == 'c') { if ((ret = _server_handle_c (g, cmd_cb, core_ptr)) < 0) { return ret; } continue; } if (r_str_startswith (g->data, "m")) { if ((ret = _server_handle_m (g, cmd_cb, core_ptr)) < 0) { return ret; } continue; } if (r_str_startswith (g->data, "QStartNoAckMode")) { if (send_ack (g) < 0 || send_msg (g, "OK") < 0) { return -1; } g->no_ack = true; continue; } // Unrecognized packet if (send_ack (g) < 0 || send_msg (g, "") < 0) { g->data[g->data_len] = '\0'; eprintf ("Unknown packet: %s\n", g->data); return -1; } }; return ret; }
void session_loop(void(*loophandler)()) { fd_set readfd, writefd; struct timeval timeout; int val; /* main loop, select()s for all sockets in use */ for(;;) { timeout.tv_sec = select_timeout(); timeout.tv_usec = 0; FD_ZERO(&writefd); FD_ZERO(&readfd); dropbear_assert(ses.payload == NULL); if (ses.sock_in != -1) { FD_SET(ses.sock_in, &readfd); } if (ses.sock_out != -1 && !isempty(&ses.writequeue)) { FD_SET(ses.sock_out, &writefd); } /* We get woken up when signal handlers write to this pipe. SIGCHLD in svr-chansession is the only one currently. */ FD_SET(ses.signal_pipe[0], &readfd); /* set up for channels which require reading/writing */ if (ses.dataallowed) { setchannelfds(&readfd, &writefd); } val = select(ses.maxfd+1, &readfd, &writefd, NULL, &timeout); if (exitflag) { dropbear_exit("Terminated by signal"); } if (val < 0 && errno != EINTR) { dropbear_exit("Error in select"); } if (val <= 0) { /* If we were interrupted or the select timed out, we still * want to iterate over channels etc for reading, to handle * server processes exiting etc. * We don't want to read/write FDs. */ FD_ZERO(&writefd); FD_ZERO(&readfd); } /* We'll just empty out the pipe if required. We don't do any thing with the data, since the pipe's purpose is purely to wake up the select() above. */ if (FD_ISSET(ses.signal_pipe[0], &readfd)) { char x; while (read(ses.signal_pipe[0], &x, 1) > 0) {} } /* check for auth timeout, rekeying required etc */ checktimeouts(); /* process session socket's incoming/outgoing data */ if (ses.sock_out != -1) { if (FD_ISSET(ses.sock_out, &writefd) && !isempty(&ses.writequeue)) { write_packet(); } } if (ses.sock_in != -1) { if (FD_ISSET(ses.sock_in, &readfd)) { read_packet(); } /* Process the decrypted packet. After this, the read buffer * will be ready for a new packet */ if (ses.payload != NULL) { process_packet(); } } /* if required, flush out any queued reply packets that were being held up during a KEX */ maybe_flush_reply_queue(); /* process pipes etc for the channels, ses.dataallowed == 0 * during rekeying ) */ if (ses.dataallowed) { channelio(&readfd, &writefd); } if (loophandler) { loophandler(); } } /* for(;;) */ /* Not reached */ }
/** * Main routine * */ static int mqtt_sub(void) { int packet_length,socket_id; uint16_t msg_id, msg_id_rcv; mqtt_broker_handle_t broker; packet_buffer.len=BUFSIZE; broker.socket_info = (void *)&socket_id; mqtt_init(&broker, "MQTT_SUB"); //mqtt_init_auth(&broker, "quijote", "rocinante"); socket_id = init_socket(&broker); // >>>>> CONNECT mqtt_connect(&broker); // <<<<< CONNACK // unsigned long pubTaskHandle= getTaskHandle(SUB_TASKID); // vTaskPrioritySet( (xTaskHandle)&pubTaskHandle, PUB_TASK_PRIORITY); //to degrade sub_task priority to let it as the same of pub_task packet_length = read_packet(1,socket_id,(Tranmit_t *)&packet_buffer); if(packet_length < 0) { UART_PRINT("Error(%d) on read packet!\n\r"); return -1; } if(MQTTParseMessageType(packet_buffer.buffer) != MQTT_MSG_CONNACK) { UART_PRINT("CONNACK expected!\n\r"); return -2; } if(packet_buffer.buffer[3] != 0x00) { UART_PRINT("CONNACK failed!\n\r"); return -2; } UART_PRINT("Connected to broker!\n\r"); if(OSI_OK != osi_TaskCreate( taskPub, (const signed char*)"taskPub", 2048, NULL, PUB_TASK_PRIORITY, (OsiTaskHandle)&pubTaskHandle )) UART_PRINT("taskPub failed\n\r"); // Signals after connect MQTT //signal(SIGALRM, alive); //alarm(keepalive); //signal(SIGINT, term); // >>>>> SUBSCRIBE mqtt_subscribe(&broker, "helloword", &msg_id); // <<<<< SUBACK packet_length = read_packet(1,socket_id,(Tranmit_t *)&packet_buffer); if(packet_length < 0) { UART_PRINT("Error(%d) on read packet!\n\r"); return -1; } if(MQTTParseMessageType(packet_buffer.buffer) != MQTT_MSG_SUBACK) { UART_PRINT("SUBACK expected!\n\r"); return -2; } msg_id_rcv = mqtt_parse_msg_id(packet_buffer.buffer); if(msg_id != msg_id_rcv) { UART_PRINT("%d message id was expected, but %d message id was found!\n\r"); return -3; } while(1) { // <<<<< packet_length = read_packet(0,socket_id,(Tranmit_t *)&packet_buffer); if(packet_length == -1) { UART_PRINT("Error(%d) on read packet!\n\r"); return -1; } else if(packet_length > 0) { UART_PRINT("Packet Header: 0x%x...\n\r"); if(MQTTParseMessageType(packet_buffer.buffer) == MQTT_MSG_PUBLISH) { uint8_t topic[TOPIC_LEN_MAX], msg[MSG_LEN_MAX]; uint16_t len; len = mqtt_parse_pub_topic(packet_buffer.buffer, topic); topic[len] = '\0'; // for printf len = mqtt_parse_publish_msg(packet_buffer.buffer, msg); msg[len] = '\0'; // for printf //UART_PRINT("%s %s\n\r", topic, msg); UART_PRINT(topic); UART_PRINT("\n\r"); UART_PRINT(msg); UART_PRINT("\n\r"); } } } return 0; }
int askConnection(in_addr host, char *login, char *pass, char *dst) { packet p; /* Packet */ current_path.nb_elmt=0; /* Size of path elmt */ char msg[strlen(ASK_CONNECT)+1]; strcpy(msg,ASK_CONNECT); strcpy(user_login,login); strcat(msg,":"); consoleLog("Asking for connection in progress...\n"); int sd=send_packet_to(host,login,dst,CMD_TYPE,msg); if(!sd) { consoleLog("Request sent to server\n"); } else { consoleError("Request not sent to server"); } int rd=read_packet(socket_descriptor,&p,False); if(rd!=0) { /* Connection reset by peer */ if(rd==22||rd==14) { return rd; } } if(strcmp(p.data_type,CMD_TYPE)) { return askConnection(host,login,pass,dst); } while(!STATE) { int comd=processCOMD(p.data,server_address,login); memset(&p,0,sizeof(packet)); if(comd==0) { STATE=1; consoleLog("You are now connected to server\n"); break; } else if(comd==-1) { // Send password char pw[strlen(SEND_PASSWORD)+2+strlen(pass)]; strcpy(pw,SEND_PASSWORD); strcat(pw,":"); strcat(pw,pass); sd=send_packet_to(host,login,dst,CMD_TYPE,pw); if(!sd) { consoleLog("Request sent to server\n"); } else { consoleError("Request not sent to server"); } } else { return comd; } int rd=read_packet(socket_descriptor,&p,False); if(rd!=0) { /* Connection reset by peer */ if(rd==22||rd==14) { return rd; } } } return 0; }
/** * Request NAKs from all clients. * Returns the aggregate number of NAKs for the section. */ int get_naks(struct finfo_t *finfo, unsigned int pass, unsigned int section, int *alldone) { unsigned char *packet, *decrypted; struct uftp_h *header; struct timeval timeout; struct sockaddr_in receiver; int resend, attempt, last_pass, gotall, anyerror; int blocks_this_sec, section_offset; int rcv_status, len, nakidx, numnaks, i, j; time_t endtime; packet = calloc(mtu, 1); decrypted = calloc(mtu, 1); if ((packet == NULL) || (decrypted == NULL)) { syserror(0, 0, "calloc failed!"); exit(1); } header = (struct uftp_h *)packet; section_offset = (blocksize * 8) * (section - 1); blocks_this_sec = ((section < finfo->sections) ? (blocksize * 8) : (finfo->blocks % (blocksize * 8))); if (finfo->sections && !blocks_this_sec) blocks_this_sec = blocksize * 8; for (i = 0; i < blocks_this_sec; i++) { nakidx = i + section_offset; finfo->naklist[nakidx] = 0; } for (i = 0; i < destcount; i++) { if (client_error(i)) { continue; } if (destlist[i].clientcnt != -1) { destlist[i].status = DEST_ACTIVE; } else if (destlist[i].status == DEST_ACTIVE) { destlist[i].status = DEST_STATUS; } free(destlist[i].last_status); destlist[i].last_status = NULL; for (j = 0; j < destlist[i].last_prstatus_cnt; j++) { free(destlist[i].last_prstatus[j]); destlist[i].last_prstatus[j] = NULL; } destlist[i].last_prstatus_cnt = 0; } endtime = time(NULL) + status_time; timeout.tv_sec = status_int / 1000; timeout.tv_usec = (status_int % 1000) * 1000; resend = 1; attempt = 1; gotall = 0; last_pass = 0; while ((time(NULL) < endtime) && (!gotall)) { if (resend) { if (!send_doneconf(finfo, attempt)) { continue; } if (!send_done(finfo, attempt, pass, section)) { continue; } resend = 0; } // See comments in announce_phase regarding timing if ((rcv_status = read_packet(sock, &receiver, packet, &len, mtu, &timeout)) == -1) { continue; } else if (rcv_status == 0) { attempt++; resend = 1; if (last_pass) break; continue; } if (!validate_packet(packet, len, finfo)) { continue; } if (!handle_transfer_phase(packet, decrypted, &receiver, blocks_this_sec, section_offset, pass, section, finfo)) { continue; } for (i = 0, gotall = 1, *alldone = 1; (i < destcount) && (gotall || *alldone); i++) { gotall = gotall && (destlist[i].status != DEST_STATUS); *alldone = *alldone && ((destlist[i].status == DEST_DONE) || (client_error(i)) || (destlist[i].clientcnt != -1)); } if (*alldone) { if (finfo->file_id != 0) break; // Change the wait interval to the client's done_int * 1.5 // to allow for late completions timeout.tv_sec = (int)(done_int / 1000 * 1.5); timeout.tv_usec = (int)((done_int % 1000) * 1000 * 1.5); if (!last_pass) { log(0, 0, "Late completions:"); } last_pass = 1; gotall = 0; send_doneconf(finfo, attempt + 1); } } anyerror = 0; if (*alldone) { send_doneconf(finfo, attempt + 1); } else if (!gotall) { for (i = 0, *alldone = 1; i < destcount; i++) { if (destlist[i].status == DEST_STATUS) { log1(0, 0, "Couldn't get STATUS from %s", destlist[i].name); destlist[i].status = DEST_LOST; anyerror = 1; } *alldone = *alldone && ((destlist[i].status == DEST_DONE) || (client_error(i)) || (destlist[i].clientcnt != -1)); } } if (anyerror && quit_on_error) { log0(0, 0, "Aboring all clients"); send_abort(finfo, "A client dropped out, aborting all", &receive_dest, NULL, (keytype != KEY_NONE), 0); for (i = 0; i < destcount; i++) { if (destlist[i].status == DEST_ACTIVE) { destlist[i].status = DEST_ABORT; } } *alldone = 1; } for (i = 0, numnaks = 0; i < blocks_this_sec; i++) { nakidx = i + section_offset; if (finfo->naklist[nakidx]) { numnaks++; } } free(packet); free(decrypted); return numnaks; }
static int cycle(mqtt_client_t* c, mqtt_timer_t* timer) { // read the socket, see what work is due int packet_type = read_packet(c, timer); int len = 0, rc = MQTT_SUCCESS; switch (packet_type) { case MQTTPACKET_CONNACK: case MQTTPACKET_PUBACK: case MQTTPACKET_SUBACK: break; case MQTTPACKET_PUBLISH: { mqtt_string_t topicName; mqtt_message_t msg; if (mqtt_deserialize_publish((unsigned char*)&msg.dup, (int*)&msg.qos, (unsigned char*)&msg.retained, (unsigned short*)&msg.id, &topicName, (unsigned char**)&msg.payload, (int*)&msg.payloadlen, c->readbuf, c->readbuf_size) != 1) goto exit; deliver_message(c, &topicName, &msg); if (msg.qos != MQTT_QOS0) { if (msg.qos == MQTT_QOS1) len = mqtt_serialize_ack(c->buf, c->buf_size, MQTTPACKET_PUBACK, 0, msg.id); else if (msg.qos == MQTT_QOS2) len = mqtt_serialize_ack(c->buf, c->buf_size, MQTTPACKET_PUBREC, 0, msg.id); if (len <= 0) rc = MQTT_FAILURE; else rc = send_packet(c, len, timer); if (rc == MQTT_FAILURE) goto exit; // there was a problem } break; } case MQTTPACKET_PUBREC: { unsigned short mypacketid; unsigned char dup, type; if (mqtt_deserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1) rc = MQTT_FAILURE; else if ((len = mqtt_serialize_ack(c->buf, c->buf_size, MQTTPACKET_PUBREL, 0, mypacketid)) <= 0) rc = MQTT_FAILURE; else if ((rc = send_packet(c, len, timer)) != MQTT_SUCCESS) // send the PUBREL packet rc = MQTT_FAILURE; // there was a problem if (rc == MQTT_FAILURE) goto exit; // there was a problem break; } case MQTTPACKET_PUBCOMP: break; case MQTTPACKET_PINGRESP: { c->ping_outstanding = 0; c->fail_count = 0; break; } case MQTT_READ_ERROR: { c->isconnected = 0; // we simulate a disconnect if reading error rc = MQTT_DISCONNECTED; // so that the outer layer will reconnect and recover break; } } if (c->isconnected) rc = keepalive(c); exit: if (rc == MQTT_SUCCESS) rc = packet_type; return rc; }
void decode_encode(struct Type** tv, int nobj) { struct my_obj objv[10]; int oix = 0; char* packet; char* inp; char* outp; char out_buf[BUFSZ]; int size1, size2, size3; int err, i; ei_x_buff arg; packet = read_packet(NULL); inp = packet+1; outp = out_buf; ei_x_new(&arg); for (i=0; i<nobj; i++) { struct Type* t = tv[i]; MESSAGE("ei_decode_%s, arg is type %s", t->name, t->type); size1 = 0; err = t->ei_decode_fp(inp, &size1, NULL); if (err != 0) { if (err != -1) { fail("decode returned non zero but not -1"); } else { fail1("decode '%s' returned non zero", t->name); } return; } if (size1 < 1) { fail("size is < 1"); return; } if (size1 > BUFSZ) { fail("size is > BUFSZ"); return; } size2 = 0; objv[oix].nterms = 0; objv[oix].startp = inp; err = t->ei_decode_fp(inp, &size2, &objv[oix]); if (err != 0) { if (err != -1) { fail("decode returned non zero but not -1"); } else { fail("decode returned non zero"); } return; } if (size1 != size2) { MESSAGE("size1 = %d, size2 = %d\n",size1,size2); fail("decode sizes differs"); return; } if (!objv[oix].nterms) { size2 = 0; err = ei_skip_term(inp, &size2); if (err != 0) { fail("ei_skip_term returned non zero"); return; } if (size1 != size2) { MESSAGE("size1 = %d, size2 = %d\n",size1,size2); fail("skip size differs"); return; } } MESSAGE("ei_encode_%s buf is NULL, arg is type %s", t->name, t->type); size2 = 0; err = t->ei_encode_fp(NULL, &size2, &objv[oix]); if (err != 0) { if (err != -1) { fail("size calculation returned non zero but not -1"); return; } else { fail("size calculation returned non zero"); return; } } if (size1 != size2) { MESSAGE("size1 = %d, size2 = %d\n",size1,size2); fail("decode and encode size differs when buf is NULL"); return; } MESSAGE("ei_encode_%s, arg is type %s", t->name, t->type); size3 = 0; err = t->ei_encode_fp(outp, &size3, &objv[oix]); if (err != 0) { if (err != -1) { fail("returned non zero but not -1"); } else { fail("returned non zero"); } return; } if (size1 != size3) { MESSAGE("size1 = %d, size2 = %d\n",size1,size3); fail("decode and encode size differs"); return; } MESSAGE("ei_x_encode_%s, arg is type %s", t->name, t->type); err = t->ei_x_encode_fp(&arg, &objv[oix]); if (err != 0) { if (err != -1) { fail("returned non zero but not -1"); } else { fail("returned non zero"); } ei_x_free(&arg); return; } if (arg.index < 1) { fail("size is < 1"); ei_x_free(&arg); return; } inp += size1; outp += size1; if (objv[oix].nterms) { /* container term */ if (++oix >= sizeof(objv)/sizeof(*objv)) fail("Term too deep"); } else { /* "leaf" term */ while (oix > 0) { if (--(objv[oix - 1].nterms) == 0) { /* last element in container */ --oix; size2 = 0; err = ei_skip_term(objv[oix].startp, &size2); if (err != 0) { fail("ei_skip_term returned non zero"); return; } if (objv[oix].startp + size2 != inp) { MESSAGE("size1 = %d, size2 = %d\n", size1, size2); fail("container skip size differs"); return; } } else break; /* more elements in container */ } } } if (oix > 0) { fail("Container not complete"); } send_buffer(out_buf, outp - out_buf); send_buffer(arg.buff, arg.index); ei_x_free(&arg); free_packet(packet); }
/* Starts running the client in given mode, parameters: struct hostent *hostname - host information int port - port used by client char *filename - file to be uploaded / downloaded Return 0 if successful. */ int runServer(int port) { int returnval = 0, t_sock = 0, filecheck = 0, rv = 0, sockSrv = 0, stopping = 0; packet *pck = NULL; init_packet *i_pck = NULL; error_packet *e_pck = NULL; clientnode *first_cl = NULL, *temp_cl = NULL; filedata *files = NULL; char *filename = NULL; char buffer[TFTP_BLOCK]; fd_set srv_fd_set; struct timeval to; /* Create socket */ if((sockSrv = socket(AF_INET,SOCK_DGRAM,0)) < 0) error("Error creating socket"); /* Set own address data */ own_address.sin_family = AF_INET; own_address.sin_addr.s_addr = htons(INADDR_ANY); own_address.sin_port = htons(port); addr_length = sizeof(struct sockaddr_in); /* Bind socket to own address */ if(bind(sockSrv,(struct sockaddr *)&own_address,addr_length) < 0) { error("Port probably in use, select another port.\nUsage:\t./server <port>\n\nError in socket binding"); } while(1) { FD_ZERO(&srv_fd_set); to.tv_sec = 0; to.tv_usec = 1; FD_SET(0,&srv_fd_set); /* If server is set to stop and wait for current connections to finish, stop listening the server socket */ if(stopping == 0) FD_SET(sockSrv,&srv_fd_set); rv = select(sockSrv+1,&srv_fd_set,NULL,NULL,&to); if (rv < 0) error("Error in select()"); else if(rv > 0) { /* Adding a client */ if(FD_ISSET(sockSrv,&srv_fd_set)) { /* Get packet */ pck = read_packet(sockSrv); printf("New connection from: %s:%d. ",(char *)inet_ntoa(get_conn_addr().sin_addr), ntohs(get_conn_addr().sin_port)); /* Create new socket */ if((t_sock = socket(AF_INET,SOCK_DGRAM,0)) < 0) perror("Error creating socket"); /* Set port and try to bind */ transfer_address.sin_family = AF_INET; transfer_address.sin_addr.s_addr = htons(INADDR_ANY); transfer_address.sin_port = htons(create_port(1)); while(bind(t_sock,(struct sockaddr *)&transfer_address,addr_length) < 0) { transfer_address.sin_port = htons(create_port(0)); } printf("Bound to port: %d. ",ntohs(transfer_address.sin_port)); /* Check packet size */ if((pck->length < 10) || (pck->length > MAX_MSG)) { pck = encode_error_packet(ERROR_ILLEGAL_OPERATION); printf("\nInvalid init packet size\n"); send_packet(t_sock,pck); close(t_sock); } else { i_pck = decode_init_packet(pck); /* If client wants to read a file */ if(ntohs(i_pck->opcode) == OPCODE_RRQ) { /* File name from packet */ filename = parse_filename(i_pck->content); printf("Requesting file \"%s\".\n",filename); first_cl = add_client(first_cl,get_conn_addr(),t_sock,filename,OPCODE_RRQ,files); if(read_file_to_block(first_cl) == -1) { pck = encode_error_packet(ERROR_NOT_FOUND); send_packet(t_sock,pck); first_cl->state = STOP; } } /* If client wants to write a file */ else if (ntohs(i_pck->opcode) == OPCODE_WRQ) { /* File name from packet */ filename = parse_filename(i_pck->content); printf("Sending file \"%s\".\n",filename); /* Check that it can be written */ if((filecheck = check_file(filename)) != 0) { pck = encode_error_packet(filecheck); send_packet(t_sock,pck); close(t_sock); } else { first_cl = add_client(first_cl,get_conn_addr(),t_sock,filename,OPCODE_WRQ,NULL); } } /* Error */ else if (ntohs(i_pck->opcode) == OPCODE_ERROR) { e_pck = decode_error_packet(pck); printf("Error from client: %s\n",e_pck->content); close(t_sock); } /* Else illegal operation */ else { pck = encode_error_packet(ERROR_ILLEGAL_OPERATION); send_packet(t_sock,pck); printf("Invalid opcode\n"); close(t_sock); } } } /* If something is typed into stdin */ if(FD_ISSET(0,&srv_fd_set)) { bzero(&buffer,TFTP_BLOCK); fgets(buffer,TFTP_BLOCK-1,stdin); /* Closing ? */ if(strcasecmp(buffer,"CLOSE\n") == 0) stopping = 1; } } temp_cl = first_cl; /* Go through clients */ while(temp_cl != NULL) { /* If not set as stopped */ if(temp_cl->state != STOP) { /* Set address info */ set_conn_addr(temp_cl->address); switch(temp_cl->mode) { case OPCODE_RRQ: upload_mode(temp_cl); break; case OPCODE_WRQ: /* If there was some error while downloading from client - try to remove the file */ if(download_mode(temp_cl) != 1) { printf("Error happened. Trying to remove unfinished file ... "); if(close(temp_cl->filed) == 0) { temp_cl->filed = -1; if(!remove(temp_cl->filename)) printf("file \"%s\" was removed.\n",temp_cl->filename); else printf("file \"%s\" cannot be removed.\n",temp_cl->filename); } } break; default: break; } } temp_cl = temp_cl->next; } /* Remove stopped clients */ first_cl = remove_stopped(first_cl); if((stopping == 1) && (first_cl == NULL)) { printf("Server stopping\n"); break; } } close(sockSrv); return returnval;
void ControlPack::loop() { read_packet(); send_heartbeat(); }
void network_thread () { /* * We loop forever waiting on either data from the ppp drivers or from * our network socket. Control handling is no longer done here. */ struct sockaddr_in from; struct in_pktinfo to; unsigned int fromlen; int tunnel, call; /* Tunnel and call */ int recvsize; /* Length of data received */ struct buffer *buf; /* Payload buffer */ struct call *c, *sc; /* Call to send this off to */ struct tunnel *st; /* Tunnel */ fd_set readfds; /* Descriptors to watch for reading */ int max; /* Highest fd */ struct timeval tv, *ptv; /* Timeout for select */ struct msghdr msgh; struct iovec iov; char cbuf[256]; unsigned int refme, refhim; int * currentfd; int server_socket_processed; #ifdef HIGH_PRIO /* set high priority */ if (setpriority(PRIO_PROCESS, 0, -20) < 0) l2tp_log (LOG_INFO, "xl2tpd: can't set priority to high: %m"); #endif /* This one buffer can be recycled for everything except control packets */ buf = new_buf (MAX_RECV_SIZE); tunnel = 0; call = 0; for (;;) { int ret; process_signal(); max = build_fdset (&readfds); ptv = process_schedule(&tv); ret = select (max + 1, &readfds, NULL, NULL, ptv); if (ret <= 0) { #ifdef DEBUG_MORE if (ret == 0) { if (gconfig.debug_network) { l2tp_log (LOG_DEBUG, "%s: select timeout\n", __FUNCTION__); } } else { if (gconfig.debug_network) { l2tp_log (LOG_DEBUG, "%s: select returned error %d (%s)\n", __FUNCTION__, errno, strerror (errno)); } } #endif continue; } if (FD_ISSET (control_fd, &readfds)) { do_control (); } server_socket_processed = 0; currentfd = NULL; st = tunnels.head; while (st || !server_socket_processed) { if (st && (st->udp_fd == -1)) { st=st->next; continue; } if (st) { currentfd = &st->udp_fd; } else { currentfd = &server_socket; server_socket_processed = 1; } if (FD_ISSET (*currentfd, &readfds)) { /* * Okay, now we're ready for reading and processing new data. */ recycle_buf (buf); /* Reserve space for expanding payload packet headers */ buf->start += PAYLOAD_BUF; buf->len -= PAYLOAD_BUF; memset(&from, 0, sizeof(from)); memset(&to, 0, sizeof(to)); fromlen = sizeof(from); memset(&msgh, 0, sizeof(struct msghdr)); iov.iov_base = buf->start; iov.iov_len = buf->len; msgh.msg_control = cbuf; msgh.msg_controllen = sizeof(cbuf); msgh.msg_name = &from; msgh.msg_namelen = fromlen; msgh.msg_iov = &iov; msgh.msg_iovlen = 1; msgh.msg_flags = 0; /* Receive one packet. */ recvsize = recvmsg(*currentfd, &msgh, 0); if (recvsize < MIN_PAYLOAD_HDR_LEN) { if (recvsize < 0) { if (errno == ECONNREFUSED) { close(*currentfd); } if ((errno == ECONNREFUSED) || (errno == EBADF)) { *currentfd = -1; } if (errno != EAGAIN) l2tp_log (LOG_WARNING, "%s: recvfrom returned error %d (%s)\n", __FUNCTION__, errno, strerror (errno)); } else { l2tp_log (LOG_WARNING, "%s: received too small a packet\n", __FUNCTION__); } if (st) st=st->next; continue; } refme=refhim=0; struct cmsghdr *cmsg; /* Process auxiliary received data in msgh */ for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL; cmsg = CMSG_NXTHDR(&msgh,cmsg)) { /* extract destination(our) addr */ if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) { struct in_pktinfo* pktInfo = ((struct in_pktinfo*)CMSG_DATA(cmsg)); to = *pktInfo; } /* extract IPsec info out */ else if (gconfig.ipsecsaref && cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == gconfig.sarefnum) { unsigned int *refp; refp = (unsigned int *)CMSG_DATA(cmsg); refme =refp[0]; refhim=refp[1]; } } /* * some logic could be added here to verify that we only * get L2TP packets inside of IPsec, or to provide different * classes of service to packets not inside of IPsec. */ buf->len = recvsize; fix_hdr (buf->start); extract (buf->start, &tunnel, &call); if (gconfig.debug_network) { l2tp_log(LOG_DEBUG, "%s: recv packet from %s, size = %d, " "tunnel = %d, call = %d ref=%u refhim=%u\n", __FUNCTION__, inet_ntoa (from.sin_addr), recvsize, tunnel, call, refme, refhim); } if (gconfig.packet_dump) { do_packet_dump (buf); } if (!(c = get_call (tunnel, call, from.sin_addr, from.sin_port, refme, refhim))) { if ((c = get_tunnel (tunnel, from.sin_addr.s_addr, from.sin_port))) { /* * It is theoretically possible that we could be sent * a control message (say a StopCCN) on a call that we * have already closed or some such nonsense. To * prevent this from closing the tunnel, if we get a * call on a valid tunnel, but not with a valid CID, * we'll just send a ZLB to ack receiving the packet. */ if (gconfig.debug_tunnel) l2tp_log (LOG_DEBUG, "%s: no such call %d on tunnel %d. Sending special ZLB\n", __FUNCTION__, call, tunnel); if (handle_special (buf, c, call) == 0) /* get a new buffer */ buf = new_buf (MAX_RECV_SIZE); } #ifdef DEBUG_MORE else { l2tp_log (LOG_DEBUG, "%s: unable to find call or tunnel to handle packet. call = %d, tunnel = %d Dumping.\n", __FUNCTION__, call, tunnel); } #endif } else { if (c->container) { c->container->my_addr = to; } buf->peer = from; /* Handle the packet */ c->container->chal_us.vector = NULL; if (handle_packet (buf, c->container, c)) { if (gconfig.debug_tunnel) l2tp_log (LOG_DEBUG, "%s: bad packet\n", __FUNCTION__); } if (c->cnu) { /* Send Zero Byte Packet */ control_zlb (buf, c->container, c); c->cnu = 0; } } } if (st) st=st->next; } /* * finished obvious sources, look for data from PPP connections. */ st = tunnels.head; while (st) { sc = st->call_head; while (sc) { if ((sc->fd >= 0) && FD_ISSET (sc->fd, &readfds)) { /* Got some payload to send */ int result; recycle_payload (buf, sc->container->peer); while ((result = read_packet (buf, sc->fd, SYNC_FRAMING)) > 0) { add_payload_hdr (sc->container, sc, buf); if (gconfig.packet_dump) { do_packet_dump (buf); } sc->prx = sc->data_rec_seq_num; if (sc->zlb_xmit) { deschedule (sc->zlb_xmit); sc->zlb_xmit = NULL; } sc->tx_bytes += buf->len; sc->tx_pkts++; udp_xmit (buf, st); recycle_payload (buf, sc->container->peer); } if (result != 0) { l2tp_log (LOG_WARNING, "%s: tossing read packet, error = %s (%d). Closing call.\n", __FUNCTION__, strerror (-result), -result); strcpy (sc->errormsg, strerror (-result)); sc->needclose = -1; } } sc = sc->next; } st = st->next; } } }
void child_session(int sock, runopts *opts, int childpipe, struct sockaddr *remoteaddr) { fd_set readfd, writefd; struct timeval timeout; int val; crypto_init(); session_init(sock, opts, childpipe, remoteaddr); /* exchange identification, version etc */ session_identification(); seedrandom(); /* start off with key exchange */ send_msg_kexinit(); FD_ZERO(&readfd); FD_ZERO(&writefd); /* main loop, select()s for network and other connections */ for(;;) { TRACE(("top of select loop")); timeout.tv_sec = SELECT_TIMEOUT; timeout.tv_usec = 0; FD_ZERO(&writefd); FD_ZERO(&readfd); assert(ses.payload == NULL); FD_SET(ses.sock, &readfd); if (!isempty(&ses.writequeue)) { FD_SET(ses.sock, &writefd); } /* set up for channels which require reading/writing */ if (ses.dataallowed == 1) { setchannelfds(&readfd, &writefd); } val = select(ses.maxfd+1, &readfd, &writefd, NULL, &timeout); TRACE(("select val = %d", val)); if (exitflag) { dropbear_exit("Terminated by signal"); } if (val < 0) { if (errno == EINTR) { continue; } else { dropbear_exit("Error in select"); } } checktimeouts(); if (val == 0) { /* timeout */ TRACE(("select timeout")); continue; } if (FD_ISSET(ses.sock, &writefd) && !isempty(&ses.writequeue)) { write_packet(); } if (FD_ISSET(ses.sock, &readfd)) { read_packet(); } /* Process the decrypted packet. After this, the read buffer * will be ready for a new packet */ if (ses.payload != NULL) { process_packet(); } /* process pipes etc for the channels */ if (ses.dataallowed == 1) { channelio(&readfd, &writefd); } } /* for(;;) */ }
int read_MPEG_system(media_entry *me, uint8 *data,uint32 *data_size, double *mtime, int *recallme, uint8 *marker) { int ret; uint32 num_bytes; int count,count1,flag,packet_done=0,not_remove=0,time_set=0,pts_diff,clock,dts_present=0,audio_flag=0; float pkt_len; static_MPEG_system *s=NULL; if (!(me->flags & ME_FD)) { if ( (ret=mediaopen(me)) < 0 ) return ret; s = (static_MPEG_system *) calloc (1, sizeof(static_MPEG_system)); me->stat = (void *) s; s->final_byte=0x00; s->offset_flag=0; s->offset=0; s->new_dts=0; } else s = (static_MPEG_system *) me->stat; num_bytes = (me->description).byte_per_pckt; *data_size=0; count=count1=0; flag = 1; lseek(me->fd,s->data_total,SEEK_SET); /* At this point it should be right to find the nearest lower frame */ /* computing it from the value of mtime */ //*data=(unsigned char *)calloc(1,65000); /* and starting the reading from this */ //if (*data==NULL) { /* feature not yet implemented */ // return ERR_ALLOC; //} if ( next_start_code(data,data_size,me->fd) == -1) { close(me->fd); return ERR_EOF; } read(me->fd,&s->final_byte,1); data[*data_size]=s->final_byte; *data_size+=1; if (s->final_byte == 0xba) { read_pack_head(data,data_size,me->fd,&s->final_byte,&s->scr); } if (s->final_byte >= 0xbc) { if (s->final_byte == 0xc0) { audio_flag = 1; } read_packet_head(data,data_size,me->fd,&s->final_byte,&time_set,&s->pts,&s->dts,&dts_present,&s->pts_audio); if (s->new_dts != 1){ s->new_dts = dts_present; } if ( (!s->offset_flag) && (s->pts.pts!=0) ) { s->offset=s->pts.pts; s->offset_flag=1; } } if (num_bytes != 0) { time_set=0; while ( ((*data_size <= num_bytes) && (*recallme == 1)) || (!packet_done) ) { count = read_packet(data,data_size,me->fd,&s->final_byte); if (!packet_done) { not_remove = 1; } else { not_remove = 0; } packet_done = 1; next_start_code(data,data_size,me->fd); read(me->fd,&s->final_byte,1); data[*data_size]=s->final_byte; *data_size+=1; if ( (s->final_byte < 0xbc) && (*data_size <= num_bytes) ) { *recallme = 0; flag = 0; // next packet coudn't stay in the same rtp packet } } if (flag && !not_remove) { count+=4; lseek(me->fd,-count,SEEK_CUR); *data_size-=count; not_remove = 0; } else { lseek(me->fd,-4,SEEK_CUR); *data_size-=4; } s->data_total+=*data_size; clock = (me->description).clock_rate; if (!audio_flag){ *mtime = ((float)(s->pts.pts-s->offset)*1000)/(float)clock; } else { *mtime = ((float)(s->pts_audio.pts-s->offset)*1000)/(float)clock; } count=0; do { /* finds next packet */ count1=next_start_code(data,data_size,me->fd); count+=count1; count+=3; read(me->fd,&s->final_byte,1); data[*data_size]=s->final_byte; *data_size+=1; count+=1; } while ((s->final_byte < 0xbc) && (s->final_byte != 0xb9) ); if (s->final_byte == 0xb9) { s->data_total+=4; } else { count1=read_packet_head(data,data_size,me->fd,&s->final_byte,&time_set,&s->next_pts,&s->next_dts,&dts_present,&s->pts_audio); /* reads next packet head */ count += count1; *data_size-=count; if ( (s->pts.pts == s->next_pts.pts) || (s->final_byte == 0xbe) || (s->final_byte == 0xc0) || (s->offset==0)) { *recallme=1; } else { if (!dts_present){ /* dts_present now is referring to the next packet */ if (!s->new_dts){ pts_diff = s->next_pts.pts - s->pts.pts; } else { pts_diff = s->next_pts.pts - s->dts.pts; } } else { pts_diff = s->next_dts.pts - s->pts.pts; } pkt_len = (((float)pts_diff*1000)/(float)clock); changePacketLength(pkt_len,me); *recallme=0; s->new_dts = 0; } /* compute the delta_mtime */ me->description.delta_mtime = (s->next_pts.pts - s->pts.pts)*1000/(float)clock; *mtime=(s->scr.scr*1000)/(double)me->description.clock_rate; /* adjust SRC value to be passed as argument to the msec2tick and do not */ } *marker=!(*recallme); return ERR_NOERROR; } else { read_packet(data,data_size,me->fd,&s->final_byte); s->data_total+=*data_size; clock = (me->description).clock_rate; if (!audio_flag){ *mtime = ((float)(s->pts.pts-s->offset)*1000)/(float)clock; } else { *mtime = ((float)(s->pts_audio.pts-s->offset)*1000)/(float)clock; } count=0; time_set=0; do { count1=next_start_code(data,data_size,me->fd); count+=count1; count+=3; read(me->fd,&s->final_byte,1); data[*data_size]=s->final_byte; *data_size+=1; count+=1; } while ((s->final_byte < 0xbc) && (s->final_byte != 0xb9) ); if (s->final_byte == 0xb9) { s->data_total+=4; } else { count1=read_packet_head(data,data_size,me->fd,&s->final_byte,&time_set,&s->next_pts,&s->next_dts,&dts_present,&s->pts_audio); count += count1; *data_size-=count; if ( (s->pts.pts == s->next_pts.pts) || (s->final_byte == 0xbe) || (s->final_byte == 0xc0) || (s->offset==0)) { *recallme=1; } else { if (!dts_present){ /* dts_present now is referring to the next packet */ if (!s->new_dts){ pts_diff = s->next_pts.pts - s->pts.pts; } else { pts_diff = s->next_pts.pts - s->dts.pts; } } else { pts_diff = s->next_dts.pts - s->pts.pts; } pkt_len = (((float)pts_diff*1000)/(float)clock); changePacketLength(pkt_len,me); *recallme=0; s->new_dts = 0; } /* compute the delta_mtime */ me->description.delta_mtime = (s->next_pts.pts - s->pts.pts)*1000/(float)clock; *mtime=(s->scr.scr*1000)/(double)me->description.clock_rate; /* adjust SRC value to be passed as argument to the msec2tick and do not */ } *marker=!(*recallme); return ERR_NOERROR; } }
void stream_pkt_receiver_t::start_listen() { m_listen_f = true; read_packet(); }
/* Handle received packets for not yet established crypto connections. */ static void receive_crypto(Net_Crypto *c) { uint32_t i; for (i = 0; i < c->crypto_connections_length; ++i) { if (c->crypto_connections[i].status == CONN_HANDSHAKE_SENT) { uint8_t temp_data[MAX_DATA_SIZE]; uint8_t secret_nonce[crypto_box_NONCEBYTES]; uint8_t public_key[crypto_box_PUBLICKEYBYTES]; uint8_t session_key[crypto_box_PUBLICKEYBYTES]; uint16_t len; if (id_packet(c->lossless_udp, c->crypto_connections[i].number) == 2) { /* Handle handshake packet. */ len = read_packet(c->lossless_udp, c->crypto_connections[i].number, temp_data); if (handle_cryptohandshake(c, public_key, secret_nonce, session_key, temp_data, len)) { if (memcmp(public_key, c->crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) { memcpy(c->crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); memcpy(c->crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); increment_nonce(c->crypto_connections[i].sent_nonce); uint32_t zero = 0; encrypt_precompute(c->crypto_connections[i].peersessionpublic_key, c->crypto_connections[i].sessionsecret_key, c->crypto_connections[i].shared_key); c->crypto_connections[i].status = CONN_ESTABLISHED; /* Connection status needs to be 3 for write_cryptpacket() to work. */ write_cryptpacket(c, i, ((uint8_t *)&zero), sizeof(zero)); c->crypto_connections[i].status = CONN_NOT_CONFIRMED; /* Set it to its proper value right after. */ } } } else if (id_packet(c->lossless_udp, c->crypto_connections[i].number) != -1) { // This should not happen, kill the connection if it does. crypto_kill(c, i); return; } } if (c->crypto_connections[i].status == CONN_NOT_CONFIRMED) { if (id_packet(c->lossless_udp, c->crypto_connections[i].number) == 3) { uint8_t temp_data[MAX_DATA_SIZE]; uint8_t data[MAX_DATA_SIZE]; int length = read_packet(c->lossless_udp, c->crypto_connections[i].number, temp_data); int len = decrypt_data(c->crypto_connections[i].peersessionpublic_key, c->crypto_connections[i].sessionsecret_key, c->crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data); uint32_t zero = 0; if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) { increment_nonce(c->crypto_connections[i].recv_nonce); encrypt_precompute(c->crypto_connections[i].peersessionpublic_key, c->crypto_connections[i].sessionsecret_key, c->crypto_connections[i].shared_key); c->crypto_connections[i].status = CONN_ESTABLISHED; /* Connection is accepted so we disable the auto kill by setting it to about 1 month from now. */ kill_connection_in(c->lossless_udp, c->crypto_connections[i].number, 3000000); } else { /* This should not happen, kill the connection if it does. */ crypto_kill(c, i); return; } } else if (id_packet(c->lossless_udp, c->crypto_connections[i].number) != -1) /* This should not happen, kill the connection if it does. */ crypto_kill(c, i); return; } } }
/* -------------------------------- input ---------------------------------- */ static void receiver(struct portinfo *pi, int childpid) { struct myiphdr ip; char packet[IP_MAX_SIZE+linkhdr_size]; while(1) { int len, iplen; len = read_packet(packet, IP_MAX_SIZE+linkhdr_size); if (len == -1) { perror("read_packet"); continue; } /* minimal sanity checks */ if (len < linkhdr_size) continue; iplen = len - linkhdr_size; if (iplen < sizeof(struct myiphdr)) continue; /* copy the ip header in an access-safe place */ memcpy(&ip, packet+linkhdr_size, sizeof(ip)); /* check if the dest IP matches */ if (memcmp(&ip.daddr, &local.sin_addr, sizeof(ip.daddr))) continue; /* check if the source IP matches */ if (ip.protocol != IPPROTO_ICMP && memcmp(&ip.saddr, &remote.sin_addr, sizeof(ip.saddr))) continue; if (ip.protocol == IPPROTO_TCP) { struct mytcphdr tcp; int iphdrlen = ip.ihl << 2; char flags[16]; time_t rttms; int sport; /* more sanity checks */ if ((iplen - iphdrlen) < sizeof(tcp)) continue; /* time to copy the TCP header in a safe place */ memcpy(&tcp, packet+linkhdr_size+iphdrlen, sizeof(tcp)); /* check if the TCP dest port matches */ #if 0 printf("SRC: %d DST: %d\n", ntohs(tcp.th_sport), ntohs(tcp.th_dport)); #endif if (ntohs(tcp.th_dport) != initsport) continue; sport = htons(tcp.th_sport); if (pi[sport].active == 0) continue; /* Note that we don't care about a wrote RTT * result due to resend on the same port. */ rttms = get_midnight_ut_ms() - pi[sport].sentms; avrgcount++; avrgms = (avrgms*(avrgcount-1)/avrgcount)+(rttms/avrgcount); /* The avrg RTT is shared using shared memory, * no locking... */ pi[MAXPORT+1].active = (int) avrgms; tcp_strflags(flags, tcp.th_flags); #if 0 printf("%5d: %s %3d %5d %5d %10ld (%2d)\n", sport, flags, ip.ttl, ip.id, ntohs(tcp.th_win), (long) rttms, opt_scan_probes-(pi[sport].retry)); #endif if ((tcp.th_flags & TH_SYN) || opt_verbose) { printf("%5d %-11.11s: %s %3d %5d %5d %5d\n", sport, port_to_name(sport), flags, ip.ttl, ip.id, ntohs(tcp.th_win), iplen); fflush(stdout); } pi[sport].active = 0; } else if (ip.protocol == IPPROTO_ICMP) { struct myicmphdr icmp; struct myiphdr subip; struct mytcphdr subtcp; int iphdrlen = ip.ihl << 2; unsigned char *p; int port; struct in_addr gwaddr; /* more sanity checks, we are only interested * in ICMP quoting the original packet. */ if ((iplen - iphdrlen) < sizeof(icmp)+sizeof(subip)+sizeof(subtcp)) continue; /* time to copy headers in a safe place */ p = (unsigned char*) packet+linkhdr_size+iphdrlen; memcpy(&icmp, p, sizeof(subtcp)); p += sizeof(icmp); memcpy(&subip, p, sizeof(ip)); p += sizeof(ip); memcpy(&subtcp, p, sizeof(subtcp)); /* Check if the ICMP quoted packet matches */ /* check if the source IP matches */ if (memcmp(&subip.saddr, &local.sin_addr, sizeof(subip.saddr))) continue; /* check if the destination IP matches */ if (memcmp(&subip.daddr, &remote.sin_addr, sizeof(subip.daddr))) continue; /* check if the quoted TCP packet port matches */ if (ntohs(subtcp.th_sport) != initsport) continue; port = htons(subtcp.th_dport); if (pi[port].active == 0) continue; pi[port].active = 0; memcpy(&gwaddr.s_addr, &ip.saddr, 4); printf("%5d: %3d %5d %5d (ICMP %3d %3d from %s)\n", port, ip.ttl, iplen, ntohs(ip.id), icmp.type, icmp.code, inet_ntoa(gwaddr)); } } }
/* Handle received packets for not yet established crypto connections. */ static void receive_crypto(Net_Crypto *c) { uint32_t i; uint64_t temp_time = unix_time(); for (i = 0; i < c->crypto_connections_length; ++i) { if (c->crypto_connections[i].status == CRYPTO_CONN_NO_CONNECTION) continue; if (c->crypto_connections[i].status == CRYPTO_CONN_HANDSHAKE_SENT) { uint8_t temp_data[MAX_DATA_SIZE]; uint8_t secret_nonce[crypto_box_NONCEBYTES]; uint8_t public_key[crypto_box_PUBLICKEYBYTES]; uint8_t session_key[crypto_box_PUBLICKEYBYTES]; uint16_t len; if (id_packet(c->lossless_udp, c->crypto_connections[i].number) == 2) { /* Handle handshake packet. */ len = read_packet(c->lossless_udp, c->crypto_connections[i].number, temp_data); if (handle_cryptohandshake(c, public_key, secret_nonce, session_key, temp_data, len)) { if (memcmp(public_key, c->crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) { memcpy(c->crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); memcpy(c->crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); increment_nonce(c->crypto_connections[i].sent_nonce); uint32_t zero = 0; encrypt_precompute(c->crypto_connections[i].peersessionpublic_key, c->crypto_connections[i].sessionsecret_key, c->crypto_connections[i].shared_key); c->crypto_connections[i].status = CRYPTO_CONN_ESTABLISHED; /* Connection status needs to be 3 for write_cryptpacket() to work. */ write_cryptpacket(c, i, ((uint8_t *)&zero), sizeof(zero)); c->crypto_connections[i].status = CRYPTO_CONN_NOT_CONFIRMED; /* Set it to its proper value right after. */ } else { /* This should not happen, timeout the connection if it does. */ c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT; } } else { /* This should not happen, timeout the connection if it does. */ c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT; } } else if (id_packet(c->lossless_udp, c->crypto_connections[i].number) != (uint8_t)~0) { /* This should not happen, timeout the connection if it does. */ c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT; } } if (c->crypto_connections[i].status == CRYPTO_CONN_NOT_CONFIRMED) { if (id_packet(c->lossless_udp, c->crypto_connections[i].number) == 3) { uint8_t temp_data[MAX_DATA_SIZE]; uint8_t data[MAX_DATA_SIZE]; int length = read_packet(c->lossless_udp, c->crypto_connections[i].number, temp_data); int len = decrypt_data(c->crypto_connections[i].peersessionpublic_key, c->crypto_connections[i].sessionsecret_key, c->crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data); uint32_t zero = 0; if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) { increment_nonce(c->crypto_connections[i].recv_nonce); encrypt_precompute(c->crypto_connections[i].peersessionpublic_key, c->crypto_connections[i].sessionsecret_key, c->crypto_connections[i].shared_key); c->crypto_connections[i].status = CRYPTO_CONN_ESTABLISHED; c->crypto_connections[i].timeout = ~0; /* Connection is accepted. */ confirm_connection(c->lossless_udp, c->crypto_connections[i].number); } else { /* This should not happen, timeout the connection if it does. */ c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT; } } else if (id_packet(c->lossless_udp, c->crypto_connections[i].number) != (uint8_t)~0) { /* This should not happen, timeout the connection if it does. */ c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT; } } if (temp_time > c->crypto_connections[i].timeout) { c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT; } } }