示例#1
0
文件: rfx_chat.cpp 项目: Feoni4/rfx
int
rfx_chat::process(rfx_event *ev, pqhead_t *pre, pqhead_t *post, evqhead_t *evq)
{
	switch (ev->what) {
	case RFXEV_SEND_REPLY:
		{
			rfx_chat_event *e = (rfx_chat_event*)ev;
			uint8_t *p;
			unsigned l = e->msg.size() > 0xf0 ? 0xf0 : e->msg.size();
			static const char tmpl[] = {
				0x02, 0x11, 0x05, 0x00, 0x00,		// magic
				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	// nick
				0xff, 0xff, 0xff, 0xff,				// ???
				0x00, 0x00, 0x01, 0x00				// ???
				/*0, ':', 0x20*/					// len + msg
			};
			rf_packet_t *pkt = pkt_new(4 + sizeof(tmpl) + 3 + l + 1, PRIVMSG_IN, SRV_TO_CLI);
			memcpy(pkt->data + 4, tmpl, sizeof(tmpl));
			p = pkt->data + 4 + 5;
			strncpy((char*)p, e->nick.c_str(), 10);
			p = pkt->data + sizeof(tmpl) + 4;
			*p++ = l + 2;
			*p++ = ':';
			*p++ = 0x20;
			memcpy(p, e->msg.c_str(), l);
			p[l] = 0;
			pqh_push(post, pkt);
			return RFX_BREAK;
		}
	}
	return RFX_DECLINE;
}
示例#2
0
struct pkt *pkt_word_list_new(char **words)
{
	int len = 0;
	int i;
	for (i = 0; words[i]; i++) {
		len += strlen(words[i]) + 1;
	}
	if (!len) {
		pkt_error("pkt_wordlist_new(): empty packet\n");
		return NULL;
	}

	char *data = malloc(len);
	if (!data) {
		pkt_error("pkt_wordlist_new(): unable to allocate %d bytes\n", len);
		return NULL;
	}
	
	int offset = 0;
	for (i = 0; words[i]; i++) {
		strcpy(data + offset, words[i]);
		offset += strlen(words[i]) + 1;
	}

	struct pkt *pkt = pkt_new(PKT_TYPE_WORD_LIST, data, len);
	return pkt;
}
示例#3
0
struct pkt *pkt_word_list_new_fixed_len(char *words, int num_words, int max_len)
{
	int len = 0;
	int i;
	for (i = 0; i < num_words; i++) {
		len += strnlen(words + i*max_len, max_len) + 1;
	}
	if (!len) {
		pkt_error("pkt_word_list_new_fixed_len(): empty packet\n");
		return NULL;
	}

	char *data = malloc(len);
	if (!data) {
		pkt_error("pkt_word_list_new_fixed_len(): unable to allocate %d bytes\n", len);
		return NULL;
	}

	int offset = 0;
	for (i = 0; i < num_words; i++) {
		int word_len = strnlen(words + i*max_len, max_len);
		memcpy(data + offset, words + i*max_len, word_len);
		offset += word_len;
		*(data + offset++) = 0;
	}
	
	struct pkt *pkt = pkt_new(PKT_TYPE_WORD_LIST, data, len);
	return pkt;	
}
示例#4
0
void receiver(int socket, char *filename)
{
	fd_set read, write;
	char readed[520];
	int f;
	if(filename==NULL)
		f=STDOUT_FILENO;
	else
		f=open(filename,O_WRONLY|O_CREAT|O_TRUNC);
	while(1){
	FD_ZERO(&read);
	FD_ZERO(&write);
	FD_SET(socket,&write);
	FD_SET(socket,&read);
	FD_SET(f,&write);
	if(select(socket+1,&read,&write, NULL,NULL)==-1)
	{
		fprintf(stderr,"Error selectreceiver\n");
		return;
	}

	if(FD_ISSET(socket,&write) && FD_ISSET(socket,&read))
	{
		printf("receiver readwritesocket\n");
		int rd=readSocket(socket,readed,520);
		if(rd>=0)
		{
			pkt_t *pkt=pkt_new();
			pkt_status_code errdec=pkt_decode((const char *)readed,(size_t)rd,pkt);
printf("lu : %s\n",pkt_get_payload(pkt));
			if(errdec==PKT_OK)
			{
				if(pkt_get_type(pkt)==PTYPE_DATA)
				{
					printf("On doit créer ACK/NACK\n");
				}
			}
			else
			{
				fprintf(stderr,"Error receiver decode\n");
				return;
			}
			pkt_del(pkt);
	printf("after del\n");
		}	
	}
	else if(FD_ISSET(f,&write))
	{
		printf("Write file\n");
		break;
	}
	}
}
示例#5
0
static void
fragroute_process(const struct pcap_pkthdr *hdr, void *buf, size_t len, void *arg)
{
    struct pktq pktq;
    struct pkt *pkt, *next;
    
    if ((pkt = pkt_new()) == NULL) {
        warn("pkt_new");
        return;
    }
    if (ETH_HDR_LEN + len > PKT_BUF_LEN) {
        warn("dropping oversized packet");
        return;
    }
    memcpy(pkt->pkt_data + ETH_HDR_LEN, buf, len);
    pkt->pkt_end = pkt->pkt_data + ETH_HDR_LEN + len;

    pkt_decorate(pkt);
    
    if (pkt->pkt_ip == NULL) {
        warn("dropping non-IP packet");
        return;
    }
    eth_pack_hdr(pkt->pkt_eth, ctx.dmac.addr_eth,
        ctx.smac.addr_eth, ETH_TYPE_IP);
    
    pkt->pkt_ip->ip_src = ctx.src.addr_ip;
    ip_checksum(pkt->pkt_ip, len);

    /* Forward this packet along as is. */
    if(ctx.dfile && 
       eth_send(ctx.eth, pkt->pkt_data, pkt->pkt_end - pkt->pkt_data) < 0)
        warn("eth_send");

    TAILQ_INIT(&pktq);
    TAILQ_INSERT_TAIL(&pktq, pkt, pkt_next);
    
    mod_apply(&pktq);

    for (pkt = TAILQ_FIRST(&pktq); pkt != TAILQ_END(&pktq); pkt = next) {
        next = TAILQ_NEXT(pkt, pkt_next);
        _resend_outgoing(pkt);
    }

}
示例#6
0
static struct pkt *
recv_pkt(struct timeval *tv)
{
	struct pcap_pkthdr phdr;
	struct timeval now, start;
	struct pkt *pkt;
	u_char *p;
	long timeout_usec;
	int i;
	
	timeout_usec = tv->tv_sec * 1000000 + tv->tv_usec;
	gettimeofday(&start, NULL);
	
	/*
	 * XXX - can't select() on pcap_fileno on Solaris,
	 * seems to be unreliable on Linux as well. *sigh*
	 */
	for (;;) {
		gettimeofday(&now, NULL);
		
		if ((p = (u_char *)pcap_next(ctx.pcap, &phdr)) != NULL ||
		    (now.tv_sec - start.tv_sec) * 1000000 +
		    now.tv_usec - start.tv_usec > timeout_usec)
			break;
	}
	if (p == NULL)
		return (NULL);
	
	p += ctx.dloff;
	i = phdr.caplen - ctx.dloff;
	
	pkt = pkt_new();
	memcpy(pkt->pkt_eth_data, p, i);
	pkt->pkt_end = pkt->pkt_eth_data + i;
	pkt_decorate(pkt);
	
	tv->tv_sec = phdr.ts.tv_sec - start.tv_sec;
	tv->tv_usec = phdr.ts.tv_usec - start.tv_usec;
	
	return (pkt);
}
示例#7
0
static mod_ret_t _iq_private_in_sess(mod_instance_t mi, sess_t sess, pkt_t pkt) {
    module_t mod = mi->mod;
    int ns, elem, target, targetns;
    st_ret_t ret;
    char filter[4096];
    os_t os;
    os_object_t o;
    nad_t nad;
    pkt_t result;
    sess_t sscan;

    /* only handle private sets and gets */
    if((pkt->type != pkt_IQ && pkt->type != pkt_IQ_SET) || pkt->ns != ns_PRIVATE)
        return mod_PASS;

    /* we're only interested in no to, to our host, or to us */
    if(pkt->to != NULL && jid_compare_user(sess->jid, pkt->to) != 0 && strcmp(sess->jid->domain, jid_user(pkt->to)) != 0)
        return mod_PASS;

    ns = nad_find_scoped_namespace(pkt->nad, uri_PRIVATE, NULL);
    elem = nad_find_elem(pkt->nad, 1, ns, "query", 1);

    /* find the first child */
    target = elem + 1;
    while(target < pkt->nad->ecur)
    {
        if(pkt->nad->elems[target].depth > pkt->nad->elems[elem].depth)
            break;

        target++;
    }

    /* not found, so we're done */
    if(target == pkt->nad->ecur)
        return -stanza_err_BAD_REQUEST;

    /* find the target namespace */
    targetns = NAD_ENS(pkt->nad, target);

    /* gotta have a namespace */
    if(targetns < 0)
    {
        log_debug(ZONE, "no namespace specified");
        return -stanza_err_BAD_REQUEST;
    }

    log_debug(ZONE, "processing private request for %.*s", NAD_NURI_L(pkt->nad, targetns), NAD_NURI(pkt->nad, targetns));

    /* get */
    if(pkt->type == pkt_IQ) {
#ifdef ENABLE_EXPERIMENTAL
        /* remember that this resource requested the namespace */
        if(sess->module_data[mod->index] == NULL) {
            /* create new hash if necesary */
            sess->module_data[mod->index] = xhash_new(101);
            pool_cleanup(sess->p, (void (*))(void *) xhash_free, sess->module_data[mod->index]);
        }
        xhash_put(sess->module_data[mod->index], pstrdupx(sess->p, NAD_NURI(pkt->nad, targetns), NAD_NURI_L(pkt->nad, targetns)), (void *) 1);
#endif
        snprintf(filter, 4096, "(ns=%i:%.*s)", NAD_NURI_L(pkt->nad, targetns), NAD_NURI_L(pkt->nad, targetns), NAD_NURI(pkt->nad, targetns));
        ret = storage_get(sess->user->sm->st, "private", jid_user(sess->jid), filter, &os);
        switch(ret) {
            case st_SUCCESS:
                if(os_iter_first(os)) {
                    o = os_iter_object(os);
                    if(os_object_get_nad(os, o, "xml", &nad)) {
                        result = pkt_new(sess->user->sm, nad_copy(nad));
                        if(result != NULL) {
                            nad_set_attr(result->nad, 1, -1, "type", "result", 6);

                            pkt_id(pkt, result);

                            pkt_sess(result, sess);

                            pkt_free(pkt);

                            os_free(os);
                
                            return mod_HANDLED;
                        }
                    }
                }

                os_free(os);

                /* drop through */
                log_debug(ZONE, "storage_get succeeded, but couldn't make packet, faking st_NOTFOUND");

            case st_NOTFOUND:

                log_debug(ZONE, "namespace not found, returning");

                /*
                 * !!! really, we should just return a 404. 1.4 just slaps a
                 *     result on the packet and sends it back. hurrah for
                 *     legacy namespaces.
                 */
                nad_set_attr(pkt->nad, 1, -1, "type", "result", 6);

                pkt_sess(pkt_tofrom(pkt), sess);
                
                return mod_HANDLED;

            case st_FAILED:
                return -stanza_err_INTERNAL_SERVER_ERROR;

            case st_NOTIMPL:
                return -stanza_err_FEATURE_NOT_IMPLEMENTED;
        }
    }

    os = os_new();
    o = os_object_new(os);

    snprintf(filter, 4096, "%.*s", NAD_NURI_L(pkt->nad, targetns), NAD_NURI(pkt->nad, targetns));
    os_object_put(o, "ns", filter, os_type_STRING);
    os_object_put(o, "xml", pkt->nad, os_type_NAD);

    snprintf(filter, 4096, "(ns=%i:%.*s)", NAD_NURI_L(pkt->nad, targetns), NAD_NURI_L(pkt->nad, targetns), NAD_NURI(pkt->nad, targetns));

    ret = storage_replace(sess->user->sm->st, "private", jid_user(sess->jid), filter, os);
    os_free(os);

    switch(ret) {
        case st_FAILED:
            return -stanza_err_INTERNAL_SERVER_ERROR;

        case st_NOTIMPL:
            return -stanza_err_FEATURE_NOT_IMPLEMENTED;

        default:
            /* create result packet */
            result = pkt_create(sess->user->sm, "iq", "result", NULL, NULL);
            pkt_id(pkt, result);
            /* and flush it to the session */
            pkt_sess(result, sess);
#ifdef ENABLE_EXPERIMENTAL
            /* push it to all resources that read this xmlns item */
            snprintf(filter, 4096, "%.*s", NAD_NURI_L(pkt->nad, targetns), NAD_NURI(pkt->nad, targetns));
            for(sscan = sess->user->sessions; sscan != NULL; sscan = sscan->next) {
                /* skip our resource and those that didn't read any private-storage */
                if(sscan == sess || sscan->module_data[mod->index] == NULL)
                    continue;

                /* check whether namespace was read */
                if(xhash_get(sscan->module_data[mod->index], filter)) {
                    result = pkt_dup(pkt, jid_full(sscan->jid), NULL);
                    if(result->from != NULL) {
                        jid_free(result->from);
                        nad_set_attr(result->nad, 1, -1, "from", NULL, 0);
                    }
                    pkt_id_new(result);
                    pkt_sess(result, sscan);
                }
            }
#endif
            /* finally free the packet */
            pkt_free(pkt);
            return mod_HANDLED;
    }

    /* we never get here */
    return 0;
}
示例#8
0
/** our master callback */
int sm_sx_callback(sx_t s, sx_event_t e, void *data, void *arg) {
    sm_t sm = (sm_t) arg;
    sx_buf_t buf = (sx_buf_t) data;
    sx_error_t *sxe;
    nad_t nad;
    pkt_t pkt;
    int len, ns, elem, attr;
    char *domain;

    switch(e) {
        case event_WANT_READ:
            log_debug(ZONE, "want read");
            mio_read(sm->mio, sm->fd);
            break;

        case event_WANT_WRITE:
            log_debug(ZONE, "want write");
            mio_write(sm->mio, sm->fd);
            break;

        case event_READ:
            log_debug(ZONE, "reading from %d", sm->fd->fd);

            /* do the read */
            len = recv(sm->fd->fd, buf->data, buf->len, 0);

            if (len < 0) {
                if (MIO_WOULDBLOCK) {
                    buf->len = 0;
                    return 0;
                }

                log_write(sm->log, LOG_NOTICE, "[%d] [router] read error: %s (%d)", sm->fd->fd, MIO_STRERROR(MIO_ERROR), MIO_ERROR);

                sx_kill(s);
                
                return -1;
            }

            else if (len == 0) {
                /* they went away */
                sx_kill(s);

                return -1;
            }

            log_debug(ZONE, "read %d bytes", len);

            buf->len = len;

            return len;

        case event_WRITE:
            log_debug(ZONE, "writing to %d", sm->fd->fd);

            len = send(sm->fd->fd, buf->data, buf->len, 0);
            if (len >= 0) {
                log_debug(ZONE, "%d bytes written", len);
                return len;
            }

            if (MIO_WOULDBLOCK)
                return 0;

            log_write(sm->log, LOG_NOTICE, "[%d] [router] write error: %s (%d)", sm->fd->fd, MIO_STRERROR(MIO_ERROR), MIO_ERROR);

            sx_kill(s);

            return -1;

        case event_ERROR:
            sxe = (sx_error_t *) data;
            log_write(sm->log, LOG_NOTICE, "error from router: %s (%s)", sxe->generic, sxe->specific);

            if(sxe->code == SX_ERR_AUTH)
                sx_close(s);

            break;

        case event_STREAM:
            break;

        case event_OPEN:
            log_write(sm->log, LOG_NOTICE, "connection to router established");

            /* set connection attempts counter */
            sm->retry_left = sm->retry_lost;

            nad = nad_new();
            ns = nad_add_namespace(nad, uri_COMPONENT, NULL);
            nad_append_elem(nad, ns, "bind", 0);
            nad_append_attr(nad, -1, "name", sm->id);
            log_debug(ZONE, "requesting component bind for '%s'", sm->id);
            sx_nad_write(sm->router, nad);
            
            if(xhash_iter_first(sm->hosts))
            do {
                xhash_iter_get(sm->hosts, (void *) &domain, &len, NULL);

                /* skip already requested SM id */
                if (strlen(sm->id) == len && strncmp(sm->id, domain, len) == 0)
                    continue;

                nad = nad_new();
                ns = nad_add_namespace(nad, uri_COMPONENT, NULL);
                elem = nad_append_elem(nad, ns, "bind", 0);
                nad_set_attr(nad, elem, -1, "name", domain, len);
                nad_append_attr(nad, -1, "multi", "to");
                log_debug(ZONE, "requesting domain bind for '%.*s'", len, domain);
                sx_nad_write(sm->router, nad);
            } while(xhash_iter_next(sm->hosts));
            
            sm_update_host = 1;
            
            break;

        case event_PACKET:
            nad = (nad_t) data;

            /* drop unqualified packets */
            if (NAD_ENS(nad, 0) < 0) {
                nad_free(nad);
                return 0;
            }
            /* watch for the features packet */
            if (s->state == state_STREAM) {
                if (NAD_NURI_L(nad, NAD_ENS(nad, 0)) != strlen(uri_STREAMS)
                    || strncmp(uri_STREAMS, NAD_NURI(nad, NAD_ENS(nad, 0)), strlen(uri_STREAMS)) != 0
                    || NAD_ENAME_L(nad, 0) != 8 || strncmp("features", NAD_ENAME(nad, 0), 8) != 0) {
                    log_debug(ZONE, "got a non-features packet on an unauth'd stream, dropping");
                    nad_free(nad);
                    return 0;
                }

#ifdef HAVE_SSL
                /* starttls if we can */
                if (sm->sx_ssl != NULL && s->ssf == 0) {
                    ns = nad_find_scoped_namespace(nad, uri_TLS, NULL);
                    if (ns >= 0) {
                        elem = nad_find_elem(nad, 0, ns, "starttls", 1);
                        if (elem >= 0) {
                            if (sx_ssl_client_starttls(sm->sx_ssl, s, NULL, NULL) == 0) {
                                nad_free(nad);
                                return 0;
                            }
                            log_write(sm->log, LOG_NOTICE, "unable to establish encrypted session with router");
                        }
                    }
                }
#endif

                /* !!! pull the list of mechanisms, and choose the best one.
                 *     if there isn't an appropriate one, error and bail */

                /* authenticate */
                sx_sasl_auth(sm->sx_sasl, s, "jabberd-router", "DIGEST-MD5", sm->router_user, sm->router_pass);

                nad_free(nad);
                return 0;
            }

            /* watch for the bind response */
            if (s->state == state_OPEN && !sm->online) {
                if (NAD_NURI_L(nad, NAD_ENS(nad, 0)) != strlen(uri_COMPONENT)
                    || strncmp(uri_COMPONENT, NAD_NURI(nad, NAD_ENS(nad, 0)), strlen(uri_COMPONENT)) != 0
                    || NAD_ENAME_L(nad, 0) != 4 || strncmp("bind", NAD_ENAME(nad, 0), 4)) {
                    log_debug(ZONE, "got a packet from router, but we're not online, dropping");
                    nad_free(nad);
                    return 0;
                }

                /* catch errors */
                attr = nad_find_attr(nad, 0, -1, "error", NULL);
                if(attr >= 0) {
                    log_write(sm->log, LOG_NOTICE, "router refused bind request (%.*s)", NAD_AVAL_L(nad, attr), NAD_AVAL(nad, attr));
                    exit(1);
                }

                log_debug(ZONE, "coming online");

                /* we're online */
                sm->online = sm->started = 1;
                log_write(sm->log, LOG_NOTICE, "%s ready for sessions", sm->id);

                nad_free(nad);
                return 0;
            }

            log_debug(ZONE, "got a packet");

            pkt = pkt_new(sm, nad);
            if (pkt == NULL) {
                log_debug(ZONE, "invalid packet, dropping");
                return 0;
            }

            /* go */
            dispatch(sm, pkt);

            return 0;

        case event_CLOSED:
            mio_close(sm->mio, sm->fd);
            sm->fd = NULL;
            return -1;
    }

    return 0;
}
示例#9
0
int
main(int argc, char *argv[])
{
	struct intf_entry ifent;
	intf_t *intf;
	int i, tests;
	char *cmd;
	
	if (argc < 3)
		usage();

	for (tests = 0, i = 1; i < argc - 1; i++) {
		cmd = argv[i];
		
		if (strcmp(cmd, "all") == 0)
			tests = ~0;
		else if (strcmp(cmd, "ping") == 0)
			tests |= TEST_PING;
		else if (strcmp(cmd, "ip-opt") == 0)
			tests |= TEST_IP_OPT;
		else if (strcmp(cmd, "ip-tracert") == 0)
			tests |= TEST_IP_TRACERT;
		else if (strcmp(cmd, "frag") == 0)
			tests |= TEST_FRAG;
		else if (strcmp(cmd, "frag-new") == 0)
			tests |= TEST_FRAG_NEW;
		else if (strcmp(cmd, "frag-old") == 0)
			tests |= TEST_FRAG_OLD;
		else if (strcmp(cmd, "frag-timeout") == 0)
			tests |= TEST_FRAG_TIMEOUT;
		else
			usage();
	}
	if (addr_aton(argv[i], &ctx.dst) < 0)
		err(1, "invalid host %s", argv[i]);

	if ((intf = intf_open()) == NULL)
		err(1, "couldn't open interface handle");

	ifent.intf_len = sizeof(ifent);
	
	if (intf_get_dst(intf, &ifent, &ctx.dst) < 0)
		err(1, "couldn't find interface for %s", addr_ntoa(&ctx.dst));
	
	memcpy(&ctx.src, &ifent.intf_addr, sizeof(ctx.src));
	ctx.src.addr_bits = IP_ADDR_BITS;
	
	intf_close(intf);
	
	if ((ctx.ip = ip_open()) == NULL)
		err(1, "couldn't open raw IP interface");

	if ((ctx.pcap = pcap_open(ifent.intf_name)) == NULL)
		err(1, "couldn't open %s for sniffing", ifent.intf_name);
	
	if ((ctx.dloff = pcap_dloff(ctx.pcap)) < 0)
		err(1, "couldn't determine link layer offset");
	
	ctx.rnd = rand_open();
	pkt_init(16);
	TAILQ_INIT(&ctx.pktq);

	ping = pkt_new();
	ip_pack_hdr(ping->pkt_ip, 0, IP_HDR_LEN + 8 + 24, 666, 0,
	    IP_TTL_DEFAULT, IP_PROTO_ICMP, ctx.src.addr_ip, ctx.dst.addr_ip);
	icmp_pack_hdr_echo(ping->pkt_icmp, ICMP_ECHO, ICMP_CODE_NONE,
	    666, 1, "AAAAAAAABBBBBBBBCCCCCCCC", 24);
	ping->pkt_end = ping->pkt_eth_data + IP_HDR_LEN + 8 + 24;
	pkt_decorate(ping);
	
	if ((tests & TEST_PING) != 0)
		test_ping();
	if ((tests & TEST_IP_OPT) != 0)
		test_ip_opt();
	if ((tests & TEST_IP_TRACERT) != 0)
		test_ip_tracert();
	if ((tests & TEST_FRAG) != 0)
		test_frag(NULL, 0);
	if ((tests & TEST_FRAG_NEW) != 0)
		test_frag("new", 0);
	if ((tests & TEST_FRAG_OLD) != 0)
		test_frag("old", 0);
	if ((tests & TEST_FRAG_TIMEOUT) != 0)
		test_frag(NULL, 1);

	rand_close(ctx.rnd);
	pcap_close(ctx.pcap);
	ip_close(ctx.ip);
	
	exit(0);
}
void getFile(const int sfd, char *filename, int out){
	//Ouverture fichier pour ecriture
	int fichier;
	if(out)
		fichier= fileno(stdin);
	else{
		fichier= open(filename, O_WRONLY|O_CREAT|O_APPEND|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
		if(fichier==-1){
			fprintf(stderr, "%s coudn't be opened.\n", filename);
			return;
		}
	}
	//Initialisations
	fd_set readfds,writefds;
	fcntl(sfd, F_SETFL, fcntl(sfd, F_GETFL, 0) | O_NONBLOCK);
	char *buffer;
	struct timeval timeout;
    timeout.tv_sec = 5;
    timeout.tv_usec = 0;
    pkt_t **stock;
    stock= malloc(sizeof(pkt_t)*WINSIZE);
    if(stock==NULL){
    	fprintf(stderr, "window allocation\n");
    	if(out!=1)
    		close(fichier);
    	return;
    }
    int k;
	for(k=0; k<=WINSIZE; k++)
		stock[k]= pkt_new();
    uint8_t seq= 0, win= (uint8_t) WINSIZE-1;
    int ack= 0, err= 0, gotEof= 0;
	ssize_t bytes_read= 0;
	pkt_t *acquis;
	struct timeval rtt;
	struct timezone zone;
	while(1){
		int ret= 0;
		FD_ZERO(&readfds);
		FD_ZERO(&writefds);
		FD_SET(sfd, &readfds);
		FD_SET(sfd, &writefds);
		if((ret=select(sfd+1,&readfds,&writefds,NULL,&timeout))<0){
			fprintf(stderr, "select()\n");
			if(out!=1)
				close(fichier);
			return;
		}
		double tmp= getRtt(rtt);
		if(gotEof && win==WINSIZE-1 && tmp>MAXRTT) 
			return;
		acquis= pkt_new();
		//Socket vers fichier
		if(FD_ISSET(sfd,&readfds) && win>=0){ //Paquet recu
			buffer= malloc(sizeof(char)*BUFSIZE);
			if(buffer==NULL){
				fprintf(stderr, "buffer allocation\n");
			}
			bytes_read= read(sfd, (void *) buffer, BUFSIZE);
			if(bytes_read==0){ //Fin. si buffer encore rempli, attend d'avoir tout recu
				if(win==WINSIZE-1)
					return;
				gotEof= 1;
			}
			else if(bytes_read<0){
				fprintf(stderr, "read(socket)\n");
			}
			else{
				pkt_t *paquet= pkt_new();
				pkt_status_code state= pkt_decode(buffer, bytes_read, paquet);
				if(state!=PKT_OK){ //normalement decode contient le header si != E_NOHEADER
					fprintf(stderr, "corrupted packet\n");
					if(bytes_read<=4 && state!=E_NOHEADER){ //Congestion
						//pkt_copy(acquis, paquet);
						acquis= paquet;
						acquis->type= PTYPE_NACK;
						acquis->window= win;
						ack= 2;
					} else //n'envoie rien
						pkt_del(paquet);
				} else{
					if(paquet->length==0)
						gotEof= 1;
					if(paquet->seqnum==seq){ //bon paquet recu
						err= write(fichier, (void *) paquet->payload, paquet->length);
						if(err==-1){
							fprintf(stderr, "write(fichier)\n");
							return;
						}
						seq++;
						pkt_del(paquet);
					} else{ //stocke le paquet en attendant le bon
						stock[paquet->seqnum%WINSIZE]= paquet;
						win--;
					}
					ack= 1;
				}
			}
			free(buffer);
		}
		// vider le buffer contenant les paquets recus et ecrire le contenu dans un fichier SI le paquet a le bon numero de sequence
		int j, nomiss= 1;
		for(j=seq%WINSIZE; j<WINSIZE && nomiss; j= (j+1)%WINSIZE){
			if(stock[j]->payload!=NULL){
				err= write(fichier, (void *) stock[j]->payload, stock[j]->length);
				if(err==-1){
					fprintf(stderr, "write(fichier)\n");
					return;
				}
				fprintf(stderr, "\tn°%d ecrit.\n", stock[j]->seqnum);
				pkt_del(stock[j]);
				stock[j]= pkt_new();
				seq++;
				win++;
			} else nomiss= 0;
		}
		//Confirmation vers Socket
		if(FD_ISSET(sfd,&writefds) && ack>0){ //Envoi acquis
			if(ack){ //acquis cumulatif
				acquis->type= PTYPE_ACK;
				acquis->window= win;
				acquis->seqnum= seq;
			}
			char *p;
			p= malloc(bytes_read*sizeof(char));
			pkt_encode(acquis, p, (size_t *) &bytes_read);
			write(sfd, (void *) p, bytes_read);
			pkt_del(acquis);
			if(gotEof && win==WINSIZE-1) //dernier acquis à envoyer
				gettimeofday(&rtt,&zone);
		}
		ack= 0;
		waitFor(0);
	}
	if(out)
		close(fichier);
	return;
}
示例#11
0
static mod_ret_t _offline_in_sess(mod_instance_t mi, sess_t sess, pkt_t pkt) {
    st_ret_t ret;
    os_t os;
    os_object_t o;
    nad_t nad;
    pkt_t queued;
    int ns, elem, attr;
    char cttl[15], cstamp[18];
    time_t ttl, stamp;

    /* if they're becoming available for the first time */
    if(pkt->type == pkt_PRESENCE && pkt->to == NULL && sess->user->top == NULL) {

        ret = storage_get(pkt->sm->st, "queue", jid_user(sess->jid), NULL, &os);
        if(ret != st_SUCCESS) {
            log_debug(ZONE, "storage_get returned %d", ret);
            return mod_PASS;
        }

        if(os_iter_first(os))
            do {
                o = os_iter_object(os);

                if(os_object_get_nad(os, o, "xml", &nad)) {
                    queued = pkt_new(pkt->sm, nad_copy(nad));
                    if(queued == NULL) {
                        log_debug(ZONE, "invalid queued packet, not delivering");
                    } else {
                        /* check expiry as necessary */
                        if((ns = nad_find_scoped_namespace(queued->nad, uri_EXPIRE, NULL)) >= 0 &&
                                (elem = nad_find_elem(queued->nad, 1, ns, "x", 1)) >= 0 &&
                                (attr = nad_find_attr(queued->nad, elem, -1, "seconds", NULL)) >= 0) {
                            snprintf(cttl, 15, "%.*s", NAD_AVAL_L(queued->nad, attr), NAD_AVAL(queued->nad, attr));
                            ttl = atoi(cttl);

                            /* it should have a x:delay stamp, because we stamp everything we store */
                            if((ns = nad_find_scoped_namespace(queued->nad, uri_DELAY, NULL)) >= 0 &&
                                    (elem = nad_find_elem(queued->nad, 1, ns, "x", 1)) >= 0 &&
                                    (attr = nad_find_attr(queued->nad, elem, -1, "stamp", NULL)) >= 0) {
                                snprintf(cstamp, 18, "%.*s", NAD_AVAL_L(queued->nad, attr), NAD_AVAL(queued->nad, attr));
                                stamp = datetime_in(cstamp);

                                if(stamp + ttl <= time(NULL)) {
                                    log_debug(ZONE, "queued packet has expired, dropping");
                                    pkt_free(queued);
                                    continue;
                                }
                            }
                        }

                        log_debug(ZONE, "delivering queued packet to %s", jid_full(sess->jid));
                        pkt_sess(queued, sess);
                    }
                }
            } while(os_iter_next(os));

        os_free(os);

        /* drop the spool */
        storage_delete(pkt->sm->st, "queue", jid_user(sess->jid), NULL);
    }

    /* pass it so that other modules and mod_presence can get it */
    return mod_PASS;
}