00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifdef HAVE_CONFIG_H
00036 # include <dtn-config.h>
00037 #endif
00038
00039 #include <stdio.h>
00040 #include <unistd.h>
00041 #include <errno.h>
00042 #include <strings.h>
00043 #include <string.h>
00044 #include <stdlib.h>
00045 #include <time.h>
00046 #include "dtn_api.h"
00047 #include <sys/stat.h>
00048
00049 #define BUFSIZE 16
00050 #define BUNDLE_DIR_DEFAULT INSTALL_LOCALSTATEDIR "/dtn/dtnperf"
00051 #define OUTFILE "dtnbuffer.rcv"
00052
00053
00054
00055
00056
00057
00058 const char *progname ;
00059 int use_file = 1;
00060
00061 int verbose = 0;
00062 int aggregate = 0;
00063 int debug = 0;
00064 char * endpoint = "/dtnperf:/dest";
00065 char * bundle_dir = BUNDLE_DIR_DEFAULT;
00066
00067
00068
00069
00070 void print_usage(char*);
00071 void parse_options(int, char**);
00072 dtn_endpoint_id_t* parse_eid(dtn_handle_t, dtn_endpoint_id_t*, char*);
00073
00074
00075
00076
00077
00078 int main(int argc, char** argv)
00079 {
00080
00081
00082
00083
00084 int k;
00085 int ret;
00086 dtn_handle_t handle;
00087 dtn_endpoint_id_t local_eid;
00088 dtn_reg_info_t reginfo;
00089 dtn_reg_id_t regid;
00090 dtn_bundle_spec_t spec;
00091 dtn_bundle_payload_t payload;
00092 char *buffer;
00093 char s_buffer[BUFSIZE];
00094 time_t current;
00095 dtn_bundle_payload_location_t pl_type = DTN_PAYLOAD_FILE;
00096
00097 int source_eid_len, dest_eid_len;
00098 char *source_eid, *dest_eid;
00099 char * filepath;
00100 char * filename = OUTFILE;
00101 int bufsize;
00102 int count = 0;
00103 int total = 0;
00104
00105
00106
00107
00108
00109
00110 printf("\nDTNperf - SERVER - v 1.6.0");
00111 printf("\nwritten by Piero Cornice <piero.cornice@gmail.com>");
00112 printf("\nDEIS - University of Bologna, Italy");
00113 printf("\n");
00114
00115
00116 parse_options(argc, argv);
00117 if (debug) printf("[debug] parsed command-line options\n");
00118
00119
00120 if (verbose) {
00121 printf("\nOptions:\n");
00122 printf("\tendpoint : %s\n", endpoint);
00123 printf("\tsave bundles to: %s\n", use_file ? "file" : "memory");
00124 printf("\tdestination dir: %s\n", bundle_dir);
00125 printf("\n");
00126 }
00127
00128
00129 if (debug) printf("[debug] initializing buffer with shell command...");
00130 buffer = malloc(sizeof(char) * (strlen(bundle_dir) + 10));
00131 sprintf(buffer, "mkdir -p %s", bundle_dir);
00132 if (debug) printf(" done. Shell command = %s\n", buffer);
00133
00134
00135 if (debug) printf("[debug] executing shell command \"%s\"...", buffer);
00136 if (system(buffer) == -1)
00137 {
00138 fprintf(stderr, "Error opening bundle directory: %s\n", bundle_dir);
00139 exit(1);
00140 }
00141 free(buffer);
00142 if (debug) printf(" done\n");
00143
00144
00145 if (debug) printf("[debug] opening connection to dtn router...");
00146 int err = dtn_open(&handle);
00147 if (err != DTN_SUCCESS) {
00148 fprintf(stderr, "fatal error opening dtn handle: %s\n",
00149 dtn_strerror(err));
00150 exit(1);
00151 }
00152 if (debug) printf(" done\n");
00153
00154
00155 if (debug) printf("[debug] building local eid...");
00156 dtn_build_local_eid(handle, &local_eid, endpoint);
00157 if (debug) printf(" done\n");
00158 if (verbose) printf("local_eid = %s\n", local_eid.uri);
00159
00160
00161 if (debug) printf("[debug] registering to local daemon...");
00162 memset(®info, 0, sizeof(reginfo));
00163 dtn_copy_eid(®info.endpoint, &local_eid);
00164 reginfo.flags = DTN_REG_DEFER;
00165 reginfo.regid = DTN_REGID_NONE;
00166 reginfo.expiration = 0;
00167 if ((ret = dtn_register(handle, ®info, ®id)) != 0) {
00168 fprintf(stderr, "error creating registration: %d (%s)\n",
00169 ret, dtn_strerror(dtn_errno(handle)));
00170 exit(1);
00171 }
00172 if (debug) printf(" done\n");
00173 if (verbose) printf("regid 0x%x\n", regid);
00174
00175
00176 if (debug) printf("[debug] choosing bundle destination type...");
00177 if (use_file)
00178 pl_type = DTN_PAYLOAD_FILE;
00179 else
00180 pl_type = DTN_PAYLOAD_MEM;
00181 if (debug) printf(" done. Bundles will be saved into %s\n", use_file ? "file" : "memory");
00182
00183 if (debug) printf("[debug] entering infinite loop...\n");
00184
00185
00186 while (1) {
00187
00188
00189 memset(&spec, 0, sizeof(spec));
00190 memset(&payload, 0, sizeof(payload));
00191
00192 if (debug) printf("[debug] waiting for bundles...");
00193 if ((ret = dtn_recv(handle, &spec, pl_type, &payload, -1)) < 0)
00194 {
00195 fprintf(stderr, "error getting recv reply: %d (%s)\n",
00196 ret, dtn_strerror(dtn_errno(handle)));
00197 exit(1);
00198 }
00199 if (debug) printf(" bundle received\n");
00200 count++;
00201
00202 size_t len;
00203 if (pl_type == DTN_PAYLOAD_MEM) {
00204 len = payload.buf.buf_len;
00205 } else {
00206 struct stat st;
00207 memset(&st, 0, sizeof(st));
00208 stat(payload.filename.filename_val, &st);
00209 len = st.st_size;
00210 }
00211
00212 total += len;
00213
00214
00215 if (debug) printf("[debug] marking time...");
00216 current = time(NULL);
00217 if (debug) printf(" done\n");
00218
00219 if (aggregate == 0) {
00220 printf("%s : %zu bytes from %s\n",
00221 ctime(¤t),
00222 len,
00223 spec.source.uri);
00224 } else if (count % aggregate == 0) {
00225 printf("%s : %d bundles, total length %d bytes\n",
00226 ctime(¤t), count, total);
00227 }
00228
00229
00230
00231
00232
00233
00234 if (debug) printf("[debug]\tcopying source eid...");
00235 source_eid_len = sizeof(spec.source.uri);
00236 source_eid = malloc(sizeof(char) * source_eid_len+1);
00237 memcpy(source_eid, spec.source.uri, source_eid_len);
00238 source_eid[source_eid_len] = '\0';
00239 if (debug) {
00240 printf(" done:\n");
00241 printf("\tsource_eid = %s\n", source_eid);
00242 printf("\n");
00243 }
00244
00245
00246 if (debug) printf("[debug]\tcopying dest eid...");
00247 dest_eid_len = sizeof(spec.dest.uri);
00248 dest_eid = malloc(sizeof(char) * dest_eid_len+1);
00249 memcpy(dest_eid, spec.dest.uri, dest_eid_len);
00250 dest_eid[dest_eid_len] = '\0';
00251 if (debug) {
00252 printf(" done:\n");
00253 printf("\tdest_eid = %s\n", dest_eid);
00254 printf("\n");
00255 }
00256
00257
00258 filepath = malloc(sizeof(char) * dest_eid_len + 10);
00259 sprintf(filepath, "mkdir -p %s", bundle_dir);
00260 if (debug) printf("[debug] filepath = %s\n", filepath);
00261 system(filepath);
00262
00263
00264 sprintf(filepath, "%s/%s", bundle_dir, filename);
00265 if (debug) printf("[debug] filepath = %s\n", filepath);
00266
00267
00268 buffer = payload.buf.buf_val;
00269 bufsize = payload.buf.buf_len;
00270
00271 if (debug) {
00272 printf ("======================================\n");
00273 printf (" Bundle received at %s\n", ctime(¤t));
00274 printf (" source: %s\n", spec.source.uri);
00275 if (use_file) {
00276 printf (" saved into : %s\n", filepath);
00277 }
00278
00279 printf ("--------------------------------------\n");
00280 }
00281
00282 if (pl_type == DTN_PAYLOAD_FILE) {
00283
00284 if (debug) printf("[debug] renaming file %s -> %s...",
00285 payload.filename.filename_val, filepath);
00286 if (rename(payload.filename.filename_val, filepath) != 0) {
00287 printf("[ERROR] Couldn't rename %s -> %s: %s\n",
00288 payload.filename.filename_val, filepath, strerror(errno));
00289 }
00290
00291 } else {
00292
00293 if (debug) {
00294 for (k=0; k < (int)payload.buf.buf_len; k++)
00295 {
00296 if (buffer[k] >= ' ' && buffer[k] <= '~')
00297 s_buffer[k%BUFSIZE] = buffer[k];
00298 else
00299 s_buffer[k%BUFSIZE] = '.';
00300
00301 if (k%BUFSIZE == 0)
00302 {
00303 printf("%07x ", k);
00304 }
00305 else if (k%2 == 0)
00306 {
00307 printf(" ");
00308 }
00309
00310 printf("%02x", buffer[k] & 0xff);
00311
00312
00313 if (k%BUFSIZE == BUFSIZE-1)
00314 {
00315 printf(" | %.*s\n", BUFSIZE, s_buffer);
00316 }
00317 }
00318
00319
00320 if (k%BUFSIZE != BUFSIZE-1) {
00321 while (k%BUFSIZE != BUFSIZE-1) {
00322 if (k%2 == 0) {
00323 printf(" ");
00324 }
00325 printf(" ");
00326 k++;
00327 }
00328 printf(" | %.*s\n",
00329 (int)payload.buf.buf_len%BUFSIZE, s_buffer);
00330 }
00331
00332 printf ("======================================\n");
00333
00334 }
00335
00336 free(filepath);
00337 free(source_eid);
00338 free(dest_eid);
00339
00340 }
00341
00342 fflush(stdout);
00343
00344 }
00345
00346
00347 dtn_close(handle);
00348
00349 return 0;
00350
00351 }
00352
00353
00354
00355
00356
00357
00358
00359
00360 void print_usage(char* progname)
00361 {
00362 fprintf(stderr, "\n");
00363 fprintf(stderr, "SYNTAX: %s [options]\n", progname);
00364 fprintf(stderr, "\n");
00365 fprintf(stderr, "options:\n");
00366 fprintf(stderr, " -d <dir>: destination directory (if using -f) \n");
00367 fprintf(stderr, " [default destination dir: %s]\n", BUNDLE_DIR_DEFAULT);
00368 fprintf(stderr, " -D: many debug messages are shown\n");
00369 fprintf(stderr, " -m: save received bundles into memory\n");
00370 fprintf(stderr, " -h: shows this help\n");
00371 fprintf(stderr, " -v: verbose\n");
00372 fprintf(stderr, " -a <n>: print message every n arrivals\n");
00373 fprintf(stderr, "\n");
00374 exit(1);
00375 }
00376
00377
00378
00379
00380 void parse_options (int argc, char** argv) {
00381 int c, done = 0;
00382
00383 while (!done) {
00384 c = getopt(argc, argv, "hvDfmd:e:a:");
00385
00386 switch(c) {
00387 case 'h':
00388 print_usage(argv[0]);
00389 exit(1);
00390 return;
00391 case 'v':
00392 verbose = 1;
00393 break;
00394 case 'D':
00395 debug = 1;
00396 break;
00397 case 'm':
00398 use_file = 0;
00399 break;
00400 case 'd':
00401 bundle_dir = optarg;
00402 break;
00403
00404 case 'e':
00405 endpoint = optarg;
00406 break;
00407
00408 case 'a':
00409 aggregate = atoi(optarg);
00410 break;
00411
00412 case -1:
00413 done = 1;
00414 break;
00415 default:
00416 print_usage(argv[0]);
00417 exit(1);
00418 }
00419 }
00420
00421 #define CHECK_SET(_arg, _what) \
00422 if (_arg == 0) { \
00423 fprintf(stderr, "\nSYNTAX ERROR: %s must be specified\n", _what); \
00424 print_usage(argv[0]); \
00425 exit(1); \
00426 }
00427
00428 }
00429
00430
00431
00432
00433 dtn_endpoint_id_t* parse_eid(dtn_handle_t handle, dtn_endpoint_id_t* eid, char * str)
00434 {
00435
00436 if (!dtn_parse_eid_string(eid, str))
00437 {
00438 return eid;
00439 }
00440
00441
00442 else if (!dtn_build_local_eid(handle, eid, str))
00443 {
00444 if (verbose) fprintf(stdout, "%s (local)\n", str);
00445 return eid;
00446 }
00447 else
00448 {
00449 fprintf(stderr, "invalid eid string '%s'\n", str);
00450 exit(1);
00451 }
00452 }