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; }
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; }
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; }
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; } } }
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); } }
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); }
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; }
/** 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; }
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; }
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; }