Exemple #1
0
/**
 * 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;
                }
            }
        }
    }
}
Exemple #2
0
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;
}
Exemple #4
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);
}
Exemple #5
0
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 */
}
Exemple #6
0
/**
 * 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;
}
Exemple #7
0
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;
}
Exemple #8
0
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;   
}
Exemple #10
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);
}
Exemple #11
0
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;
}
Exemple #12
0
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(&reginfo, 0, sizeof(reginfo));
    dtn_copy_eid(&reginfo.endpoint, &bundle_spec.replyto);
    reginfo.flags = DTN_REG_DEFER;
    reginfo.regid = regid;
    reginfo.expiration = 0;
    if ((ret = dtn_register(handle, &reginfo, &regid)) != 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
}
Exemple #15
0
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;
}
Exemple #18
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;
}
Exemple #19
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;
}
Exemple #20
0
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;
}
Exemple #21
0
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);
}
Exemple #22
0
/*	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;
Exemple #23
0
void ControlPack::loop()
{
    read_packet();
    send_heartbeat();
}
Exemple #24
0
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;
        }
    }

}
Exemple #25
0
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(;;) */
}
Exemple #26
0
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();
}
Exemple #28
0
/* 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;
        }
    }
}
Exemple #29
0
/* -------------------------------- 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;
        }
    }
}