3 * swift the multiparty transport protocol
5 * Created by Victor Grishchenko on 2/15/10.
6 * Copyright 2010 Delft University of Technology. All rights reserved.
14 using namespace swift;
16 #define quit(...) {fprintf(stderr,__VA_ARGS__); exit(1); }
17 SOCKET InstallHTTPGateway (Address addr);
20 int main (int argc, char** argv) {
22 static struct option long_options[] =
24 {"hash", required_argument, 0, 'h'},
25 {"file", required_argument, 0, 'f'},
26 {"daemon", no_argument, 0, 'd'},
27 {"listen", required_argument, 0, 'l'},
28 {"tracker", required_argument, 0, 't'},
29 {"debug", no_argument, 0, 'D'},
30 {"progress",no_argument, 0, 'p'},
31 {"http", optional_argument, 0, 'g'},
32 {"wait", optional_argument, 0, 'w'},
38 bool daemonize = false, report_progress = false;
47 while ( -1 != (c = getopt_long (argc, argv, ":h:f:dl:t:Dpg::w::", long_options, 0)) ) {
51 if (strlen(optarg)!=40)
52 quit("SHA1 hash must be 40 hex symbols\n");
53 root_hash = Sha1Hash(true,optarg); // FIXME ambiguity
54 if (root_hash==Sha1Hash::ZERO)
55 quit("SHA1 hash must be 40 hex symbols\n");
58 filename = strdup(optarg);
64 bindaddr = Address(optarg);
65 if (bindaddr==Address())
66 quit("address must be hostname:port, ip:port or just port\n");
68 wait_time = TINT_NEVER; // seed
71 tracker = Address(optarg);
72 if (tracker==Address())
73 quit("address must be hostname:port, ip:port or just port\n");
77 Channel::debug_file = optarg ? fopen(optarg,"a") : stdout;
80 report_progress = true;
83 http_gw = optarg ? Address(optarg) : Address(Address::LOCALHOST,8080);
85 wait_time = TINT_NEVER; // seed
88 wait_time = TINT_NEVER;
91 if (sscanf(optarg,"%lli%c",&wait_time,&unit)!=2)
92 quit("time format: 1234[umsMHD], e.g. 1M = one minute\n");
94 case 'D': wait_time *= 24;
95 case 'H': wait_time *= 60;
96 case 'M': wait_time *= 60;
97 case 's': wait_time *= 1000;
98 case 'm': wait_time *= 1000;
100 default: quit("time format: 1234[umsMHD], e.g. 1D = one day\n");
106 } // arguments parsed
109 if (bindaddr!=Address()) { // seeding
110 if (Listen(bindaddr)<=0)
111 quit("cant listen to %s\n",bindaddr.str())
112 } else if (tracker!=Address() || http_gw!=Address()) { // leeching
113 for (int i=0; i<=10; i++) {
114 bindaddr = Address((uint32_t)INADDR_ANY,0);
115 if (Listen(bindaddr)>0)
118 quit("cant listen on %s\n",bindaddr.str());
122 if (tracker!=Address())
125 if (http_gw!=Address())
126 InstallHTTPGateway(http_gw);
128 if (root_hash!=Sha1Hash::ZERO && !filename)
129 filename = strdup(root_hash.hex().c_str());
133 file = Open(filename,root_hash);
135 quit("cannot open file %s",filename);
136 printf("Root hash: %s\n", RootMerkleHash(file).hex().c_str());
139 if (bindaddr==Address() && file==-1) {
140 fprintf(stderr,"Usage:\n");
141 fprintf(stderr," -h, --hash\troot Merkle hash for the transmission\n");
142 fprintf(stderr," -f, --file\tname of file to use (root hash by default)\n");
143 fprintf(stderr," -l, --listen\t[ip:|host:]port to listen to (default: random)\n");
144 fprintf(stderr," -t, --tracker\t[ip:|host:]port of the tracker (default: none)\n");
145 fprintf(stderr," -D, --debug\tfile name for debugging logs (default: stdout)\n");
146 fprintf(stderr," -p, --progress\treport transfer progress\n");
147 fprintf(stderr," -g, --http\t[ip:|host:]port to bind HTTP gateway to (default localhost:8080)\n");
148 fprintf(stderr," -w, --wait\tlimit running time, e.g. 1[DHMs] (default: infinite with -l, -g)\n");
151 tint start_time = NOW;
153 while ( bindaddr!=Address() &&
154 ( ( file>=0 && !IsComplete(file) ) ||
155 ( start_time+wait_time > NOW ) ) ) {
156 swift::Loop(TINT_SEC);
157 if (report_progress && file>=0) {
159 "%s %lli of %lli (seq %lli) %lli dgram %lli bytes up, "\
160 "%lli dgram %lli bytes down\n",
161 IsComplete(file) ? "DONE" : "done",
162 Complete(file), Size(file), SeqComplete(file),
163 Datagram::dgrams_up, Datagram::bytes_up,
164 Datagram::dgrams_down, Datagram::bytes_down );
171 if (Channel::debug_file)
172 fclose(Channel::debug_file);