Exemple #1
0
void
make_registration(dtn_reg_info_t* reginfo)
{
	int ret;

        // try to find an existing registration to use (unless we're
        // using session flags, in which case we always create a new
        // registration)
        if (session_flags == 0) {
            ret = dtn_find_registration(handle, &reginfo->endpoint, &regid);

            if (ret == 0) {
                
                // found the registration, bind it to the handle
                if (dtn_bind(handle, regid) != DTN_SUCCESS) {
                    fprintf(stderr, "%s: error in bind (id=0x%x): %d (%s)\n",
                            progname, regid, ret, dtn_strerror(dtn_errno(handle)));
                    exit(EXIT_FAILURE);
                }
                
                return;
                
            } else if (dtn_errno(handle) == DTN_ENOTFOUND) {
                // fall through
                
            } else {
                fprintf(stderr, "%s: error in dtn_find_registration: %d (%s)\n",
                        progname, ret, dtn_strerror(dtn_errno(handle)));
                exit(EXIT_FAILURE);
            }
        }

        // create a new dtn registration to receive bundles
	if ((ret = dtn_register(handle, reginfo, &regid)) != 0) {
            fprintf(stderr, "%s: error creating registration (id=0x%x): %d (%s)\n",
                    progname, regid, ret, dtn_strerror(dtn_errno(handle)));
            exit(EXIT_FAILURE);
        }
    
        if (verbose)
            fprintf(info, "dtn_register succeeded, regid 0x%x\n", regid);
}
Exemple #2
0
void
to_bundles()
{

    int bytes, ret;
    dtn_reg_info_t reg_report; /* for reports, if reqd */
    dtn_reg_info_t reg_session; /* for session reg, if reqd */
	
    // initialize bundle spec
    memset(&bundle_spec, 0, sizeof(bundle_spec));
    parse_eid(handle, &bundle_spec.dest, arg_dest);
    parse_eid(handle, &bundle_spec.source, arg_source);

    if (arg_replyto == NULL) {
        dtn_copy_eid(&bundle_spec.replyto, &bundle_spec.source);
    } else {
        parse_eid(handle, &bundle_spec.replyto, arg_replyto);
    }

    if (verbose) {
        print_eid(info, "source_eid", &bundle_spec.source);
        print_eid(info, "replyto_eid", &bundle_spec.replyto);
        print_eid(info, "dest_eid", &bundle_spec.dest);
    }

    if (wait_for_report) {
	// if we're given a regid, bind to it, otherwise make a
	// registration for incoming reports
        if (regid != DTN_REGID_NONE) {
            if (dtn_bind(handle, regid) != DTN_SUCCESS) {
                fprintf(stderr, "%s: error in bind (id=0x%x): %d (%s)\n",
                        progname, regid, ret, dtn_strerror(dtn_errno(handle)));
                exit(EXIT_FAILURE);
            }
        } else {
            memset(&reg_report, 0, sizeof(reg_report));
            dtn_copy_eid(&reg_report.endpoint, &bundle_spec.replyto);
            reg_report.flags = DTN_REG_DEFER;
            reg_report.expiration = REG_EXPIRE;
            make_registration(&reg_report);
        }
    }

    if (session_flags) {
        // make a publisher registration 
        memset(&reg_session, 0, sizeof(reg_session));
	dtn_copy_eid(&reg_session.endpoint, &bundle_spec.dest);
        reg_session.flags = DTN_SESSION_PUBLISH;
        reg_session.expiration = 0;
	make_registration(&reg_session);
    }
    
    // set the dtn options
    bundle_spec.expiration = expiration;
    
    if (delivery_receipts) {
        // set the delivery receipt option
        bundle_spec.dopts |= DOPTS_DELIVERY_RCPT;
    }

    if (forwarding_receipts) {
        // set the forward receipt option
        bundle_spec.dopts |= DOPTS_FORWARD_RCPT;
    }

    if (custody) {
        // request custody transfer
        bundle_spec.dopts |= DOPTS_CUSTODY;
    }

    if (custody_receipts) {
        // request custody transfer
        bundle_spec.dopts |= DOPTS_CUSTODY_RCPT;
    }

    if (receive_receipts) {
        // request receive receipt
        bundle_spec.dopts |= DOPTS_RECEIVE_RCPT;
    }

    if (sequence_id) {
        bundle_spec.sequence_id.data.data_val = sequence_id;
        bundle_spec.sequence_id.data.data_len = strlen(sequence_id);
    }

    if (obsoletes_id) {
        bundle_spec.obsoletes_id.data.data_val = obsoletes_id;
        bundle_spec.obsoletes_id.data.data_len = strlen(obsoletes_id);
    }

    if ((bytes = fill_payload(&primary_payload)) < 0) {
	fprintf(stderr, "%s: error reading bundle data\n",
	    progname);
	exit(EXIT_FAILURE);
    }

    memset(&bundle_id, 0, sizeof(bundle_id));
    if ((ret = dtn_send(handle, regid, &bundle_spec, &primary_payload,
                        &bundle_id)) != 0) {
	fprintf(stderr, "%s: error sending bundle: %d (%s)\n",
	    progname, ret, dtn_strerror(dtn_errno(handle)));
	exit(EXIT_FAILURE);
    }

    if (verbose)
        fprintf(info, "Read %d bytes from stdin and wrote to bundles\n",
		bytes);

    if (wait_for_report) {
	memset(&reply_spec, 0, sizeof(reply_spec));
	memset(&reply_payload, 0, sizeof(reply_payload));
	
	// now we block waiting for any replies
	if ((ret = dtn_recv(handle, &reply_spec,
			    DTN_PAYLOAD_MEM, &reply_payload, -1)) < 0) {
	    fprintf(stderr, "%s: error getting reply: %d (%s)\n",
		    progname, ret, dtn_strerror(dtn_errno(handle)));
	    exit(EXIT_FAILURE);
	}
	if (gettimeofday(&end, NULL) < 0) {
	    fprintf(stderr, "%s: gettimeofday(end) returned error %s\n",
		    progname, strerror(errno));
	    exit(EXIT_FAILURE);
	}
    
	if (verbose)
	    fprintf(info, "got %d byte report from [%s]: time=%.1f ms\n",
	       reply_payload.buf.buf_len,
	       reply_spec.source.uri,
	       ((double)(end.tv_sec - start.tv_sec) * 1000.0 + 
		(double)(end.tv_usec - start.tv_usec)/1000.0));
    }
}
Exemple #3
0
int
main(int argc, char** argv)
{
    int i, errs;
    int ret;
    dtn_handle_t handle;
    dtn_endpoint_id_t local_eid;
    dtn_reg_info_t reginfo;
    dtn_bundle_spec_t spec;
    dtn_bundle_payload_t payload;
    int call_bind;
    time_t now;

    // force stdout to always be line buffered, even if output is
    // redirected to a pipe or file
    setvbuf(stdout, (char *)NULL, _IOLBF, 0);
    
    progname = argv[0];

    parse_options(argc, argv);

    printf("dtnsink starting up -- waiting for %u bundles\n", count);

    // open the ipc handle
    if (verbose) printf("opening connection to dtn router...\n");
    int err = dtn_open(&handle);
    if (err != DTN_SUCCESS) {
        fprintf(stderr, "fatal error opening dtn handle: %s\n",
                dtn_strerror(err));
        exit(1);
    }
    if (verbose) printf("opened connection to dtn router...\n");

    // if we're not given a regid, or we're in change mode, we need to
    // build up the reginfo
    memset(&reginfo, 0, sizeof(reginfo));

    if ((regid == DTN_REGID_NONE) || change)
    {
        // if the specified eid starts with '/', then build a local
        // eid based on the configuration of our dtn router plus the
        // demux string. otherwise make sure it's a valid one
        if (endpoint[0] == '/') {
            if (verbose) printf("calling dtn_build_local_eid.\n");
            dtn_build_local_eid(handle, &local_eid, (char *) endpoint);
            if (verbose) printf("local_eid [%s]\n", local_eid.uri);
        } else {
            if (verbose) printf("calling parse_eid_string\n");
            if (dtn_parse_eid_string(&local_eid, endpoint)) {
                fprintf(stderr, "invalid destination endpoint '%s'\n",
                        endpoint);
                goto err;
            }
        }

        // create a new registration based on this eid
        dtn_copy_eid(&reginfo.endpoint, &local_eid);
        reginfo.regid             = regid;
        reginfo.expiration        = expiration;
        reginfo.flags             = failure_action;
        reginfo.script.script_val = failure_script;
        reginfo.script.script_len = strlen(failure_script) + 1;
    }

    if (change) {
        if ((ret = dtn_change_registration(handle, regid, &reginfo)) != 0) {
            fprintf(stderr, "error changing registration: %d (%s)\n",
                    ret, dtn_strerror(dtn_errno(handle)));
            goto err;
        }
        printf("change registration succeeded, regid %d\n", regid);
        goto done;
    }
    
    if (unregister) {
        if (dtn_unregister(handle, regid) != 0) {
            fprintf(stderr, "error in unregister regid %d: %s\n",
                    regid, dtn_strerror(dtn_errno(handle)));
            goto err;
        }
        
        printf("unregister succeeded, regid %d\n", regid);
        goto done;
    }
    
    // try to see if there is an existing registration that matches
    // the given endpoint, in which case we'll use that one.
    if (regid == DTN_REGID_NONE && ! no_find_reg) {
        if (dtn_find_registration(handle, &local_eid, &regid) != 0) {
            if (dtn_errno(handle) != DTN_ENOTFOUND) {
                fprintf(stderr, "error in find_registration: %s\n",
                        dtn_strerror(dtn_errno(handle)));
                goto err;
            }
        }
        printf("find registration succeeded, regid %d\n", regid);
        call_bind = 1;
    }
    
    // if the user didn't give us a registration to use, get a new one
    if (regid == DTN_REGID_NONE) {
        if ((ret = dtn_register(handle, &reginfo, &regid)) != 0) {
            fprintf(stderr, "error creating registration: %d (%s)\n",
                    ret, dtn_strerror(dtn_errno(handle)));
            goto err;
        }

        printf("register succeeded, regid %d\n", regid);
        call_bind = 0;
    } else {
        call_bind = 1;
    }
    
    if (register_only) {
        goto done;
    }

    if (call_bind) {
        // bind the current handle to the found registration
        printf("binding to regid %d\n", regid);
        if (dtn_bind(handle, regid) != 0) {
            fprintf(stderr, "error binding to registration: %s\n",
                    dtn_strerror(dtn_errno(handle)));
            goto err;
        }
    }

    // keep track of what we've seen
    char *received = (char *)malloc(count + 1);
    memset(received, '\0', count);

    // loop waiting for bundles
    fprintf(stderr, "waiting %d seconds for first bundle...\n",
	    (MAX_STARTUP_TRIES)*RECV_TIMEOUT/1000);
    for (i = 1; i <= count; ++i) {
	int tries;
	uint32_t which;
	uint32_t size;

        memset(&spec, 0, sizeof(spec));
        memset(&payload, 0, sizeof(payload));

	/* 
	 * this is a little tricky. We want dtn_recv to time out after
	 * RECV_TIMEOUT ms, so we don't wait a long time for a bundle
	 * if something is broken and no bundle is coming.  But we
	 * want to be friendly and wait patiently for the first
	 * bundle, in case dtnsource is slow in getting off the mark.
	 * 
	 * So we loop at most MAX_STARTUP_TRIES times
	 */
	tries = 0;
	while ((ret = dtn_recv(handle, &spec, bundletype, &payload, 
			       RECV_TIMEOUT)) < 0) {
	    /* if waiting for the first bundle and we timed out be patient */
	    if (dtn_errno(handle) == DTN_ETIMEOUT) {
		if (i == 1 && ++tries < MAX_STARTUP_TRIES) {
		    fprintf(stderr, "waiting %d seconds for first bundle...\n",
			    (MAX_STARTUP_TRIES-tries)*RECV_TIMEOUT/1000);
		} else {
		    /* timed out waiting, something got dropped */
		    fprintf(stderr, "timeout waiting for bundle %d\n", i);
		    goto bail;
		}
	    } else {
	        /* a bad thing has happend in recv, or we've lost patience */
		fprintf(stderr, "error in dtn_recv: %d (%d, %s)\n", ret, 
			dtn_errno(handle), dtn_strerror(dtn_errno(handle)));
		goto bail;
	    }
	}

	if (i == 1) {
	    now = time(0);
	    printf("received first bundle at %s\n", ctime(&now));
	}
	if (verbose) {
	    printf("bundle %d received successfully: id %s,%llu.%llu\n",
		   i,
		   spec.source.uri,
		   spec.creation_ts.secs,
		   spec.creation_ts.seqno);
	}

	if (!promiscuous) {
	    /* check to see which bundle this is */
	    // Files need to be handled differently than memory transfers
	    if (payload.location == DTN_PAYLOAD_FILE) {
		if (handle_file_transfer(payload, &size, &which) < 0) {
		    dtn_free_payload(&payload);
		    continue;
		}
	    } else {
		which = ntohl(*(uint32_t *)payload.buf.buf_val);
		size = payload.buf.buf_len;
	    }
	    
	    if (which > (uint32_t) count) {
		// note that the above cast is safe as count always >= 0
		fprintf(stderr, "-- expecting %d bundles, saw bundle %u\n", 
			count, which);
	    }
	    else if (which <= 0) { /* because I am paranoid -DJE */
		fprintf(stderr, "-- didn't expect bundle %u\n", which);
	    }
	    else {
	      ++received[which];
	    }
	}

	// XXX should verify size here...

	/* all done, get next one */
	dtn_free_payload(&payload);
    }

bail:
    for (i = 1; i <= count; ++i) {
	if (received[i] == 0) {
	    int j = i + 1;
	    while (j <= count && received[j] == 0)
		++j;
	    if (j == i + 1)
		printf("bundle %d: dropped\n", i);
	    else
		printf("bundles %d-%d dropped\n", i, j - 1);
	    errs += (j - i);
	    i += (j - i - 1);
	} else if (received[i] > 1) {
	    printf("bundle %d: received %d copies\n", i, received[i]);
	    ++errs;
	}
    }
    if (errs == 0) {
	printf("all %d bundles received correctly\n", count);
    }
    free(received);
    now = time(0);
    printf("terminating at %s\n", ctime(&now));

done:
    dtn_close(handle);
    return 0;

err:
    dtn_close(handle);
    return 1;
}