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