// Ctrl+C handler void server_handler(int sig) { printf("\nDTNperf server received SIGINT: Exiting\n"); server_clean_exit(0); }
/* ---------------------------- * SERVER CODE * ---------------------------- */ void run_dtnperf_server(dtnperf_global_options_t * perf_g_opt) { /* ------------------------ * variables * ------------------------ */ dtnperf_options_t * perf_opt = perf_g_opt->perf_opt; dtnperf_connection_options_t * conn_opt = perf_g_opt->conn_opt; al_bp_reg_info_t reginfo; al_bp_bundle_payload_location_t pl_location; al_bp_endpoint_id_t bundle_source_addr; al_bp_endpoint_id_t bundle_dest_addr; al_bp_endpoint_id_t bundle_replyto_addr; al_bp_error_t error; al_bp_bundle_object_t bundle_object; al_bp_bundle_object_t bundle_ack_object; al_bp_bundle_delivery_opts_t bundle_ack_dopts; al_bp_timestamp_t bundle_creation_timestamp; al_bp_timeval_t bundle_expiration; al_bp_bundle_priority_t bundle_priority; size_t bundle_payload_len; dtnperf_server_ack_payload_t server_ack_payload; HEADER_TYPE bundle_header; dtnperf_bundle_ack_options_t bundle_ack_options; time_t current; char* command = NULL; char* pl_filename = NULL; size_t pl_filename_len = 0; char* pl_buffer = NULL; char temp[256]; size_t pl_buffer_size = 0; boolean_t is_file_transfer_bundle; int indicator; // for file transfer functions purposes int num_ack; // for name file bundle ack /* ------------------------ * initialize variables * ------------------------ */ boolean_t debug = perf_g_opt->perf_opt->debug; int debug_level = perf_g_opt->perf_opt->debug_level; perf_opt->dest_dir = correct_dirname(perf_opt->dest_dir); perf_opt->file_dir = correct_dirname(perf_opt->file_dir); bp_handle_open = FALSE; num_ack=0; // initialize structures for file transfers file_transfer_info_list = file_transfer_info_list_create(); // set out buffer size if daemon if (perf_opt->daemon) { setlinebuf(stdout); setlinebuf(stderr); } // show requested options (debug) if (debug) { printf("\nOptions;\n"); printf("\tendpoint:\t%s\n", perf_opt->bp_implementation == BP_ION ? SERV_EP_NUM_SERVICE : SERV_EP_STRING); printf("\tsave bundles to:\t%s\n", perf_opt->use_file ? "file":"memory"); if(perf_opt->use_file) printf("\tdestination dir:\t%s\n", perf_opt->dest_dir); printf("\tsend acks:\t%s\n", perf_opt->no_acks ? "no":"yes"); if (!perf_opt->no_acks) { //printf("\tsend acks to monitor: %s\n", perf_opt->acks_to_mon ? "yes":"no"); printf("\tacks expiration time: %d\n", (int) conn_opt->expiration); char * prior; switch(conn_opt->priority.priority) { case BP_PRIORITY_BULK: prior = "bulk"; break; case BP_PRIORITY_NORMAL: prior = "normal"; break; case BP_PRIORITY_EXPEDITED: prior = "expedited"; break; case BP_PRIORITY_RESERVED: prior = "reserved"; break; default: prior = "unknown"; break; } printf("\tacks priority : %s\n", prior); } printf("\n"); } //Ctrl+C handler signal(SIGINT, server_handler); // create dir where dtnperf server will save incoming bundles // command should be: mkdir -p "dest_dir" if(debug && debug_level > 0) printf("[debug] initializing shell command..."); command = malloc(sizeof(char) * (30 + strlen(perf_opt->dest_dir))); sprintf(command, "mkdir -p %s && rm /tmp/ion_*", perf_opt->dest_dir); if(debug && debug_level > 0) printf("done. Shell command = %s\n", command); // execute shell command if(debug && debug_level > 0) printf("[debug] executing shell command..."); if (system(command) < 0) { perror("[DTNperf error] in opening bundle destination dir"); exit(-1); } free(command); if(debug && debug_level > 0) printf("done\n"); // create dir where dtnperf server will save incoming files // command should be: mkdir -p "file_dir" if(debug && debug_level > 0) printf("[debug] initializing shell command..."); command = malloc(sizeof(char) * (10 + strlen(perf_opt->file_dir))); sprintf(command, "mkdir -p %s", perf_opt->file_dir); if(debug && debug_level > 0) printf("done. Shell command = %s\n", command); // execute shell command if(debug && debug_level > 0) printf("[debug] executing shell command..."); if (system(command) < 0) { perror("[DTNperf error] in opening transferred files destination dir"); exit(-1); } free(command); if(debug && debug_level > 0) printf("done\n"); //open the connection to the bundle protocol router if(debug && debug_level > 0) printf("[debug] opening connection to bundle protocol router..."); if (perf_opt->use_ip) error = al_bp_open_with_ip(perf_opt->ip_addr, perf_opt->ip_port, &handle); else error = al_bp_open(&handle); if (error != BP_SUCCESS) { fflush(stdout); fprintf(stderr, "[DTNperf fatal error] in opening bp handle: %s\n", al_bp_strerror(error)); exit(1); } else { bp_handle_open = TRUE; } if(debug && debug_level > 0) printf("done\n"); //build a local eid if(debug && debug_level > 0) { printf("[debug] building a local eid in format "); if (perf_opt->eid_format_forced == 'D') printf("forced DTN..."); else if (perf_opt->eid_format_forced == 'I') printf("forced IPN..."); else printf("standard..."); } if(perf_opt->bp_implementation == BP_ION && perf_opt->eid_format_forced == 'N') // Use ION implementation with standard eid scheme error = al_bp_build_local_eid(handle, &local_eid, SERV_EP_NUM_SERVICE,CBHE_SCHEME); else if(perf_opt->bp_implementation == BP_DTN && perf_opt->eid_format_forced == 'N') // Use DTN2 implementation with standard eid scheme error = al_bp_build_local_eid(handle, &local_eid, SERV_EP_STRING,DTN_SCHEME); else if(perf_opt->bp_implementation == BP_ION && perf_opt->eid_format_forced == 'D') // Use ION implementation with forced DTN scheme error = al_bp_build_local_eid(handle, &local_eid, SERV_EP_STRING,DTN_SCHEME); else if(perf_opt->bp_implementation == BP_DTN && perf_opt->eid_format_forced == 'I') // Use DTN2 implementation with forced IPN scheme { //in this case the api al_bp_build_local_eid() wants ipn_local_number.service_number sprintf(temp, "%d.%s", perf_opt->ipn_local_num, SERV_EP_NUM_SERVICE); error = al_bp_build_local_eid(handle, &local_eid, temp, CBHE_SCHEME); } if(debug && debug_level > 0) printf("done\n"); if (debug) printf("local_eid = %s\n", local_eid.uri); if (error != BP_SUCCESS) { fflush(stdout); fprintf(stderr, "[DTNperf fatal error] in building local EID: '%s'\n", al_bp_strerror(error)); server_clean_exit(1); } // checking if there is already a registration if(debug && debug_level > 0) printf("[debug] checking for existing registration..."); error = al_bp_find_registration(handle, &local_eid, ®id); if ( (error == BP_SUCCESS && perf_opt->bp_implementation == BP_DTN) || (perf_opt->bp_implementation == BP_ION && (error == BP_EBUSY || error == BP_EPARSEEID))) { fflush(stdout); fprintf(stderr, "[DTNperf error] existing a registration with the same eid.\n"); fprintf(stderr, "regid 0x%x\n", (unsigned int) regid); server_clean_exit(1); } if ((debug) && (debug_level > 0)) printf(" done\n"); //create a new registration to the local router based on this eid if(debug && debug_level > 0) printf("[debug] registering to local daemon..."); memset(®info, 0, sizeof(reginfo)); al_bp_copy_eid(®info.endpoint, &local_eid); reginfo.flags = BP_REG_DEFER; reginfo.regid = BP_REGID_NONE; reginfo.expiration = 0; if ((error = al_bp_register(&handle, ®info, ®id)) != 0) { fflush(stdout); fprintf(stderr, "[DTNperf error] in creating registration: %d (%s)\n", error, al_bp_strerror(al_bp_errno(handle))); server_clean_exit(1); } if ((debug) && (debug_level > 0)) printf(" done\n"); if (debug) printf("regid 0x%x\n", (unsigned int) regid); // set bundle destination type if ((debug) && (debug_level > 0)) printf("[debug] choosing bundle destination type..."); if (perf_opt->use_file) pl_location = BP_PAYLOAD_FILE; else pl_location = BP_PAYLOAD_MEM; if ((debug) && (debug_level > 0)) printf(" done. Bundles will be saved into %s\n", perf_opt->use_file ? "file" : "memory"); // start thread pthread_mutex_init (&mutexdata, NULL); pthread_create(&file_exp_timer, NULL, file_expiration_timer, NULL); if ((debug) && (debug_level > 0)) printf("[debug] entering infinite loop...\n"); // start infinite loop while(1) { // create a bundle object if ((debug) && (debug_level > 0)) printf("[debug] initiating memory for bundles...\n"); error = al_bp_bundle_create(&bundle_object); if (error != BP_SUCCESS) { fflush(stdout); fprintf(stderr, "[DTNperf fatal error] in initiating memory for bundles: %s\n", al_bp_strerror(error)); server_clean_exit(1); } if(debug && debug_level > 0) printf("done\n"); // reset file transfer indicators is_file_transfer_bundle = FALSE; // wait until receive a bundle if ((debug) && (debug_level > 0)) printf("[debug] waiting for bundles...\n"); error = al_bp_bundle_receive(handle, bundle_object, pl_location, -1); if(error == BP_ERECVINT || error == BP_ETIMEOUT) { if(error == BP_ERECVINT ) fprintf(stderr, "[DTNperf warning] bundle reception interrupted\n"); if(error == BP_ETIMEOUT ) fprintf(stderr, "[DTNperf warning] bundle reception timeout expired\n"); // free memory for bundle al_bp_bundle_free(&bundle_object); } else { if (error != BP_SUCCESS) { fflush(stdout); fprintf(stderr, "error getting recv reply: %d (%s)\n", error, al_bp_strerror(al_bp_errno(handle))); server_clean_exit(1); } if ((debug) && (debug_level > 0)) printf(" bundle received\n"); // find payload size if ((debug) && (debug_level > 0)) printf("[debug] calculating bundle payload size..."); error = al_bp_bundle_get_payload_size(bundle_object, (u32_t *) &bundle_payload_len); if (error != BP_SUCCESS) { fflush(stdout); fprintf(stderr, "[DTNperf fatal error] in getting bundle payload size: %s\n", al_bp_strerror(error)); server_clean_exit(1); } if(debug && debug_level > 0) printf("done\n"); // mark current time if ((debug) && (debug_level > 0)) printf("[debug] marking time..."); current = time(NULL); if ((debug) && (debug_level > 0)) printf(" done\n"); // print bundle arrival printf("%s : %zu bytes from %s\n", ctime(¤t), bundle_payload_len, bundle_object.spec->source.uri); // get bundle header and options if ((debug) && (debug_level > 0)) printf("[debug]\tgetting bundle header and options..."); if (get_bundle_header_and_options(&bundle_object, &bundle_header, &bundle_ack_options) < 0) { printf("[DTNperf warning] in getting bundle header and options\n"); continue; } if ((debug) && (debug_level > 0)) { printf(" done.\n"); } // get SOURCE eid if ((debug) && (debug_level > 0)) printf("[debug]\tgetting source eid..."); error = al_bp_bundle_get_source(bundle_object, &bundle_source_addr); if (error != BP_SUCCESS) { fflush(stdout); fprintf(stderr, "[DTNperf fatal error] in getting bundle source eid: %s\n", al_bp_strerror(error)); server_clean_exit(1); } if ((debug) && (debug_level > 0)) { printf(" done:\n"); printf("\tbundle_source_addr = %s\n", bundle_source_addr.uri); printf("\n"); } // get DEST eid if ((debug) && (debug_level > 0)) printf("[debug]\tgetting destination eid..."); error = al_bp_bundle_get_dest(bundle_object, &bundle_dest_addr); if (error != BP_SUCCESS) { fflush(stdout); fprintf(stderr, "[DTNperf fatal error] in getting bundle destination eid: %s\n", al_bp_strerror(error)); server_clean_exit(1); } if ((debug) && (debug_level > 0)) { printf(" done:\n"); printf("\tbundle_dest_eid = %s\n", bundle_dest_addr.uri); printf("\n"); } // get REPLY TO eid if ((debug) && (debug_level > 0)) printf("[debug]\tgetting reply to eid..."); error = al_bp_bundle_get_replyto(bundle_object, &bundle_replyto_addr); if (error != BP_SUCCESS) { fflush(stdout); fprintf(stderr, "error getting bundle reply to eid: %s\n", al_bp_strerror(error)); exit(1); } if ((debug) && (debug_level > 0)) { printf(" done:\n"); printf("\tbundle_replyto_eid = %s\n", bundle_replyto_addr.uri); printf("\n"); } // get bundle creation timestamp if ((debug) && (debug_level > 0)) printf("[debug]\tgetting bundle creation timestamp..."); error = al_bp_bundle_get_creation_timestamp(bundle_object, &bundle_creation_timestamp); if (error != BP_SUCCESS) { fflush(stdout); fprintf(stderr, "[DTNperf fatal error] in getting bundle creation timestamp: %s\n", al_bp_strerror(error)); server_clean_exit(1); } if ((debug) && (debug_level > 0)) { printf(" done:\n"); printf("\tbundle creation timestamp:\n" "\tsecs = %d\n\tseqno= %d\n", (int)bundle_creation_timestamp.secs, (int)bundle_creation_timestamp.seqno); printf("\n"); } // get bundle payload filename if(perf_opt->use_file) { if ((debug) && (debug_level > 0)) printf("[debug]\tgetting bundle payload filename..."); error = al_bp_bundle_get_payload_file(bundle_object, &pl_filename, (u32_t *) &pl_filename_len); if (error != BP_SUCCESS) { fflush(stdout); fprintf(stderr, "[DTNperf fatal error] in getting bundle payload filename: %s\n", al_bp_strerror(error)); server_clean_exit(1); } if ((debug) && (debug_level > 0)) { printf(" done:\n"); } } if ((debug)) { printf ("======================================\n"); printf (" Bundle received at %s\n", ctime(¤t)); printf (" source: %s\n", bundle_source_addr.uri); if (perf_opt->use_file) { printf (" saved into : %s\n", pl_filename); } printf ("--------------------------------------\n"); }; // check if is file transfer bundle if ((debug) && (debug_level > 0)) printf("[debug]\tchecking if this is a file transfer bundle..."); if (bundle_header == FILE_HEADER) { is_file_transfer_bundle = TRUE; } if ((debug) && (debug_level > 0)) { printf(" done.\n"); printf("\tbundle is%sa file transfer bundle\n", is_file_transfer_bundle ? " " : " not "); printf("\n"); } int crc_ok = 1; if (bundle_ack_options.crc_enabled==TRUE) { FILE *pl_stream; char *transfer; int transfer_len; u32_t pl_size; uint32_t local_crc; local_crc = 0; crc_ok = 0; // get info about bundle size al_bp_bundle_get_payload_size(bundle_object, &pl_size); if (open_payload_stream_read(bundle_object, &pl_stream) < 0) { fflush(stdout); fprintf(stderr, "[DTNperf fatal error] i can't open the bundle file\n"); server_clean_exit(1); } /* fseek(pl_stream, HEADER_SIZE + BUNDLE_OPT_SIZE, SEEK_SET); if (is_file_transfer_bundle) { fseek }*/ transfer_len = HEADER_SIZE + BUNDLE_OPT_SIZE+sizeof(al_bp_timeval_t); transfer = (char*) malloc(transfer_len); memset(transfer, 0, transfer_len); if (fread(transfer, transfer_len, 1, pl_stream) != 1 && ferror(pl_stream)!=0) { fprintf(stderr, "[DTNperf warning] in processing file transfer bundle: %s\n", strerror(errno)); } local_crc = calc_crc32_d8(local_crc, (uint8_t*) transfer, transfer_len); free(transfer); fseek(pl_stream, BUNDLE_CRC_SIZE, SEEK_CUR); transfer_len = pl_size-transfer_len-BUNDLE_CRC_SIZE; transfer = (char*) malloc(transfer_len); memset(transfer, 0, transfer_len); if (fread(transfer, transfer_len, 1, pl_stream) != 1 && ferror(pl_stream)!=0) { fprintf(stderr, "[DTNperf warning] in processing file transfer bundle: %s\n", strerror(errno)); } local_crc = calc_crc32_d8(local_crc, (uint8_t*) transfer, transfer_len); if (debug) printf("CRC received: %"PRIu32" GENERATED: %"PRIu32"\n", bundle_object.payload->buf.buf_crc, local_crc); if (local_crc != bundle_object.payload->buf.buf_crc) bundle_ack_options.crc_enabled=TRUE; else bundle_ack_options.crc_enabled=FALSE; if (bundle_ack_options.crc_enabled==FALSE) { crc_ok = 1; } free(transfer); close_payload_stream_read(pl_stream); } // process file transfer bundle if(is_file_transfer_bundle && crc_ok == 1) { if ((debug) && (debug_level > 0)) printf("[debug]\tprocessing file transfer bundle..."); pthread_mutex_lock(&mutexdata); indicator = process_incoming_file_transfer_bundle(&file_transfer_info_list, &bundle_object,perf_opt->file_dir, (bundle_ack_options.crc_enabled == TRUE ? &bundle_object.payload->buf.buf_crc : (uint32_t *) NULL)); pthread_mutex_unlock(&mutexdata); sched_yield(); // WRONG CRC //if (indicator == -2) //{ // if (debug) // printf("CRC differs from the received one.\n"); // bundle_ack_options.crc_enabled=TRUE; //} //else // bundle_ack_options.crc_enabled=FALSE; if (indicator < 0) // error in processing bundle { fprintf(stderr, "[DTNperf warning] in processing file transfer bundle: %s\n", strerror(errno)); } if ((debug) && (debug_level > 0)) { printf("done.\n"); if (indicator == 1) printf("Transfer Completed\n"); } } // get bundle expiration time if (bundle_ack_options.set_ack_expiration) { // al_bp_bundle_get_expiration(bundle_object, &bundle_expiration); // is setted the smaller if( conn_opt->expiration < bundle_ack_options.ack_expiration) bundle_expiration = conn_opt->expiration; else bundle_expiration = bundle_ack_options.ack_expiration; } else bundle_expiration = conn_opt->expiration; // get bundle priority bundle_priority.ordinal = 0; if( bundle_ack_options.set_ack_priority) { // is setted the smaller if( conn_opt->priority.priority < bundle_ack_options.ack_priority.priority) bundle_priority.priority = conn_opt->priority.priority; else bundle_priority.priority = bundle_ack_options.ack_priority.priority; } else bundle_priority.priority = conn_opt->priority.priority; // send acks to the client only if requested by client // send acks to the monitor if: // ack requested by client AND ack-to-monitor option set AND bundle_ack_options.ack_to_mon == ATM_NORMAL // OR client forced server to send ack to monitor boolean_t send_ack_to_client = bundle_ack_options.ack_to_client; boolean_t send_ack_to_monitor = FALSE; send_ack_to_monitor = (bundle_ack_options.ack_to_client && (bundle_ack_options.ack_to_mon == ATM_NORMAL) && bundle_ack_options.ack_to_client && perf_opt->acks_to_mon) || (bundle_ack_options.ack_to_mon == ATM_FORCE_YES); if (send_ack_to_client || send_ack_to_monitor) { // create bundle ack to send if ((debug) && (debug_level > 0)) printf("[debug] initiating memory for bundle ack..."); error = al_bp_bundle_create(&bundle_ack_object); if (error != BP_SUCCESS) { fflush(stdout); fprintf(stderr, "[DTNperf fatal error] in initiating memory for bundle ack: %s\n", al_bp_strerror(error)); server_clean_exit(1); } if(debug && debug_level > 0) printf("done\n"); // initiate server ack payload // set server ack payload source server_ack_payload.bundle_source = bundle_source_addr; // set server ack payload timestamp server_ack_payload.bundle_creation_ts = bundle_creation_timestamp; // preparing the bundle ack payload if ((debug) && (debug_level > 0)) printf("[debug] preparing the payload of the bundle ack..."); error = prepare_server_ack_payload(server_ack_payload, &bundle_ack_options, &pl_buffer, &pl_buffer_size); if (error != BP_SUCCESS) { fflush(stdout); fprintf(stderr, "[DTNperf fatal error] in preparing the payload of the bundle ack: %s\n", al_bp_strerror(error)); server_clean_exit(1); } if(debug && debug_level > 0) printf("done\n"); // setting the bundle ack payload if ((debug) && (debug_level > 0)) printf("[debug] setting the payload of the bundle ack..."); // For DTN2 implementation ack payload in in memory if(perf_opt->bp_implementation == BP_DTN) { error = al_bp_bundle_set_payload_mem(&bundle_ack_object, pl_buffer, pl_buffer_size); } else if(perf_opt->bp_implementation == BP_ION) { char filename_ack[256]; FILE * fd_ack; u32_t filename_ack_len; sprintf(filename_ack,"%s_%d",SOURCE_FILE_ACK,num_ack); filename_ack_len = strlen(filename_ack)+1; fd_ack = fopen(filename_ack,"w"); if(fd_ack == NULL) { fflush(stdout); fprintf(stderr, "[DTNperf fatal error] in creating the payload of the bundle ack: %s\n", strerror(errno)); server_clean_exit(1); } if(fwrite(pl_buffer, pl_buffer_size, 1, fd_ack)<0){ fflush(stdout); fprintf(stderr, "[DTNperf fatal error] in writing the payload of the bundle ack: %s\n", strerror(errno)); //server_clean_exit(1); } if (fclose(fd_ack) != 0){ fflush(stdout); fprintf(stderr, "[DTNperf fatal error] in closing the payload file of the bundle ack: %s\n", strerror(errno)); server_clean_exit(1); } if (debug && debug_level > 0) { printf("\n[debug] bundle payload ack saved in: %s ... ", filename_ack); } num_ack++; if (num_ack == 10000) //reset ack counter when it arrives at 10000 num_ack = 0; error = al_bp_bundle_set_payload_file(&bundle_ack_object,filename_ack,filename_ack_len); } if (error != BP_SUCCESS) { fflush(stdout); fprintf(stderr, "\n[DTNperf fatal error] in setting the payload of the bundle ack: %s\n", al_bp_strerror(error)); server_clean_exit(1); } if(debug && debug_level > 0) printf("done\n"); // setting the bundle ack options if (debug && debug_level > 0) { printf("[debug] setting source of the bundle ack: %s ...", local_eid.uri); } error = al_bp_bundle_set_source(& bundle_ack_object, local_eid); if (error != BP_SUCCESS) { fflush(stdout); fprintf(stderr, "[DTNperf fatal error] in setting the source of the bundle ack: %s\n", al_bp_strerror(error)); server_clean_exit(1); } if(debug && debug_level > 0) printf("done\n"); if (debug && debug_level > 0) { printf("[debug] setting destination of the bundle ack: %s ...", bundle_source_addr.uri); } error = al_bp_bundle_set_dest(& bundle_ack_object, bundle_source_addr); if (error != BP_SUCCESS) { fflush(stdout); fprintf(stderr, "[DTNperf fatal error] in setting the destination of the bundle ack: %s\n", al_bp_strerror(error)); server_clean_exit(1); } if(debug && debug_level > 0) printf("done\n"); if (debug && debug_level > 0) { printf("[debug] setting replyto eid of the bundle ack: %s ...", bundle_replyto_addr.uri); } error = al_bp_bundle_set_replyto(& bundle_ack_object, bundle_replyto_addr); if (error != BP_SUCCESS) { fflush(stdout); fprintf(stderr, "[DTNperf fatal error] in setting the reply to eid of the bundle ack: %s\n", al_bp_strerror(error)); server_clean_exit(1); } if(debug && debug_level > 0) printf("done\n"); if (debug && debug_level > 0) { printf("[debug] setting priority of the bundle ack..."); } error = al_bp_bundle_set_priority(& bundle_ack_object, bundle_priority); if (error != BP_SUCCESS) { fflush(stdout); fprintf(stderr, "[DTNperf fatal error] in setting priority of the bundle ack: %s\n", al_bp_strerror(error)); server_clean_exit(1); } if(debug && debug_level > 0) printf("done\n"); /**************************************************************/ bundle_ack_object.spec->priority.ordinal = 0; bundle_ack_object.spec->critical = FALSE; bundle_ack_object.spec->flow_label = 0; bundle_ack_object.spec->unreliable = FALSE; /**************************************************************/ if (debug && debug_level > 0) { printf("[debug] setting expiration time of the bundle ack..."); } error = al_bp_bundle_set_expiration(& bundle_ack_object, bundle_expiration); if (error != BP_SUCCESS) { fflush(stdout); fprintf(stderr, "[DTNperf fatal error] in setting expiration time of the bundle ack: %s\n", al_bp_strerror(error)); server_clean_exit(1); } if(debug && debug_level > 0) printf("done\n"); if (debug && debug_level > 0) { printf("[debug] setting delivery options of the bundle ack..."); } //bundle_ack_dopts = BP_DOPTS_CUSTODY; bundle_ack_dopts = 0; al_bp_bundle_set_delivery_opts(& bundle_ack_object, bundle_ack_dopts); if (error != BP_SUCCESS) { fflush(stdout); fprintf(stderr, "[DTNperf fatal error] in setting delivery options of the bundle ack: %s\n", al_bp_strerror(error)); server_clean_exit(1); } if(debug && debug_level > 0) printf("done\n"); // send the bundle ack to the client if (send_ack_to_client) { if ((debug) && (debug_level > 0)) printf("[debug] sending bundle ack to client..."); error = al_bp_bundle_send(handle, regid, & bundle_ack_object); if (error != BP_SUCCESS) { fflush(stdout); fprintf(stderr, "[DTNperf fatal error] in sending bundle ack to client: %d (%s)\n", error, al_bp_strerror(al_bp_errno(handle))); server_clean_exit(1); } if ((debug) && (debug_level > 0)) printf(" bundle ack sent to client\n"); } printf("Send bundle to client ok\n"); // send the bundle ack to the monitor if (send_ack_to_monitor) { al_bp_bundle_set_dest(& bundle_ack_object, bundle_replyto_addr); if ((debug) && (debug_level > 0)) printf("[debug] sending bundle ack to monitor..."); error = al_bp_bundle_send(handle, regid, & bundle_ack_object); if (error != BP_SUCCESS) { fflush(stdout); fprintf(stderr, "[DTNperf fatal error] in sending bundle ack to monitor: %d (%s)\n", error, al_bp_strerror(al_bp_errno(handle))); server_clean_exit(1); } if ((debug) && (debug_level > 0)) printf(" bundle ack sent to monitor\n"); } //free memory for bundle ack al_bp_bundle_free(&bundle_ack_object); free(pl_buffer); pl_buffer_size = 0; } // free memory for bundle al_bp_bundle_free(&bundle_object); free(pl_filename); pl_filename_len = 0; } }// while(1) al_bp_close(handle); //al_bp_unregister(handle,regid,local_eid); bp_handle_open = FALSE; }