static int callback_connect(void * cookie, int s) { struct netproto_connect_cookie * C = cookie; int rc; /* The connect is no longer pending. */ C->connect_cookie = NULL; /* Did the connection attempt fail? */ if (s == -1) { /* * Call the upstream callback. Upon being informed that the * connect has failed, the upstream code is responsible for * calling netproto_close, which (since we haven't called * netproto_setfd yet) will call into callback_cancel and let * us clean up. */ return ((C->callback)(C->cookie, NETWORK_STATUS_CONNERR)); } /* Inform the netproto code that we have a socket. */ if (netproto_setfd(C->NC, s)) goto err2; /* Perform key exchange. */ if (netproto_keyexchange(C->NC, C->useragent, C->callback, C->cookie)) goto err1; /* Free the cookie. */ sock_addr_freelist(C->sas); free(C->useragent); free(C); /* Success! */ return (0); err2: /* Drop the socket since we can't use it properly. */ close(s); err1: /* Call the upstream callback. */ rc = (C->callback)(C->cookie, NETWORK_STATUS_ERR); /* * We've called netproto_setfd, so callback_cancel won't happen; we * are responsible for cleaning up after ourselves. */ sock_addr_freelist(C->sas); free(C->useragent); free(C); /* Return value from user callback. */ return (rc); }
int main(int argc, char * argv[]) { struct sock_addr ** sas; uintmax_t N; int s; struct wire_requestqueue * Q; WARNP_INIT; /* Check number of arguments. */ if (argc != 3) { fprintf(stderr, "usage: hotspot_read %s N\n", "<socketname>"); exit(1); } /* Parse N. */ if ((N = strtoumax(argv[2], NULL, 0)) == 0) { warnp("Invalid value for N: %s", argv[2]); exit(1); } /* Resolve the socket address and connect. */ if ((sas = sock_resolve(argv[1])) == NULL) { warnp("Error resolving socket address: %s", argv[1]); exit(1); } if (sas[0] == NULL) { warn0("No addresses found for %s", argv[1]); exit(1); } if ((s = sock_connect(sas)) == -1) exit(1); /* Create a request queue. */ if ((Q = wire_requestqueue_init(s)) == NULL) { warnp("Cannot create packet write queue"); exit(1); } /* Start issuing hotspot read requests. */ if (hotspotread(Q, N)) exit(1); /* Free the request queue. */ wire_requestqueue_destroy(Q); wire_requestqueue_free(Q); /* Free socket addresses. */ sock_addr_freelist(sas); /* Shut down the event subsystem. */ events_shutdown(); /* Success! */ exit(0); }
static int found(void * cookie, struct sock_addr ** sas) { char * addr; int i; (void)cookie; /* UNUSED */ /* Sanity check. */ if (sas == NULL) goto err0; /* Print each address. */ for (i = 0; i < MAX_ADDRS; i++) { if (sas[i] == NULL) break; /* Extract address and print it. */ if ((addr = sock_addr_prettyprint(sas[i])) == NULL) { warn0("sock_addr_prettyprint()"); goto err1; } printf("%s\n", addr); /* Clean up. */ free(addr); } /* Clean up. */ sock_addr_freelist(sas); /* Quit event loop. */ doneloop = 1; /* Success! */ return (0); err1: sock_addr_freelist(sas); err0: /* Failure! */ return (-1); }
int main(int argc, char * argv[]) { struct sock_addr ** sas; int s; struct wire_requestqueue * Q; WARNP_INIT; /* Check number of arguments. */ if (argc != 2) { fprintf(stderr, "usage: bulk_insert %s\n", "<socketname>"); exit(1); } /* Resolve the socket address and connect. */ if ((sas = sock_resolve(argv[1])) == NULL) { warnp("Error resolving socket address: %s", argv[1]); exit(1); } if (sas[0] == NULL) { warn0("No addresses found for %s", argv[1]); exit(1); } if ((s = sock_connect(sas)) == -1) exit(1); /* Create a request queue. */ if ((Q = wire_requestqueue_init(s)) == NULL) { warnp("Cannot create packet write queue"); exit(1); } /* Start bulk inserting. */ if (bulkinsert(Q, stdin)) exit(1); /* Free the request queue. */ wire_requestqueue_destroy(Q); wire_requestqueue_free(Q); /* Free socket addresses. */ sock_addr_freelist(sas); /* Shut down the event subsystem. */ events_shutdown(); /* Success! */ exit(0); }
/** * proto_conn_drop(conn_cookie): * Drop connection and frees memory associated with ${conn_cookie}. Return * success or failure. */ int proto_conn_drop(void * conn_cookie) { struct conn_state * C = conn_cookie; int rc; /* Close the incoming connection. */ close(C->s); /* Close the outgoing connection if it is open. */ if (C->t != -1) close(C->t); /* Stop connecting if a connection is in progress. */ if (C->connect_cookie != NULL) network_connect_cancel(C->connect_cookie); /* Free the target addresses if we haven't already done so. */ sock_addr_freelist(C->sas); /* Stop handshaking if a handshake is in progress. */ if (C->handshake_cookie != NULL) proto_handshake_cancel(C->handshake_cookie); /* Kill timeouts if they are pending. */ if (C->connect_timeout_cookie != NULL) events_timer_cancel(C->connect_timeout_cookie); if (C->handshake_timeout_cookie != NULL) events_timer_cancel(C->handshake_timeout_cookie); /* Free protocol keys. */ proto_crypt_free(C->k_f); proto_crypt_free(C->k_r); /* Shut down pipes. */ if (C->pipe_f != NULL) proto_pipe_cancel(C->pipe_f); if (C->pipe_r != NULL) proto_pipe_cancel(C->pipe_r); /* Notify the upstream that we've dropped a connection. */ rc = (C->callback_dead)(C->cookie); /* Free the connection cookie. */ free(C); /* Return success/fail status. */ return (rc); }
/** * netproto_connect(useragent, callback, cookie): * Create a socket, connect to the tarsnap server, and perform the necessary * key exchange. Return a network protocol connection cookie; note that * this cookie must not be used until the callback is called. */ NETPROTO_CONNECTION * netproto_connect(const char * useragent, network_callback * callback, void * cookie) { struct netproto_connect_cookie * C; struct timeval timeo; /* Create a cookie to be passed to callback_connect. */ if ((C = malloc(sizeof(struct netproto_connect_cookie))) == NULL) goto err0; if ((C->useragent = strdup(useragent)) == NULL) goto err1; C->callback = callback; C->cookie = cookie; /* Look up the server's IP address. */ if ((C->sas = getserveraddr()) == NULL) goto err2; /* Try to connect to server, waiting up to 5 seconds per address. */ timeo.tv_sec = 5; timeo.tv_usec = 0; if ((C->connect_cookie = network_connect_timeo(C->sas, &timeo, callback_connect, C)) == NULL) { netproto_printerr(NETWORK_STATUS_CONNERR); goto err3; } /* Create a network protocol connection cookie. */ if ((C->NC = netproto_alloc(callback_cancel, C)) == NULL) goto err4; /* Success! */ return (C->NC); err4: network_connect_cancel(C->connect_cookie); err3: sock_addr_freelist(C->sas); err2: free(C->useragent); err1: free(C); err0: /* Failure! */ return (NULL); }
/* We have connected to the target. */ static int callback_connect_done(void * cookie, int t) { struct conn_state * C = cookie; /* This connection attempt is no longer pending. */ C->connect_cookie = NULL; /* Don't need the target address any more. */ sock_addr_freelist(C->sas); C->sas = NULL; /* We beat the clock. */ events_timer_cancel(C->connect_timeout_cookie); C->connect_timeout_cookie = NULL; /* Did we manage to connect? */ if ((C->t = t) == -1) return (dropconn(C)); /* If we're encrypting, start the handshake. */ if (!C->decr) { if (starthandshake(C, C->t, C->decr)) goto err1; } /* If we have connections and keys, start shuttling data. */ if ((C->t != -1) && (C->k_f != NULL) && (C->k_r != NULL)) { if (launchpipes(C)) goto err1; } /* Success! */ return (0); err1: dropconn(C); /* Failure! */ return (-1); }
static int callback_cancel(void * cookie) { struct netproto_connect_cookie * C = cookie; int rc; /* Cancel the connection attempt if still pending. */ if (C->connect_cookie != NULL) network_connect_cancel(C->connect_cookie); /* We were cancelled. */ rc = (C->callback)(C->cookie, NETWORK_STATUS_CANCEL); /* Free our cookie. */ sock_addr_freelist(C->sas); free(C->useragent); free(C); /* Return value from user callback. */ return (rc); }
int main(int argc, char * argv[]) { /* State variables. */ int * socks_s; int sock_t; struct wire_requestqueue * Q_t; struct dispatch_state * dstate; /* Command-line parameters. */ intmax_t opt_n = 0; char * opt_p = NULL; char * opt_t = NULL; ADDRLIST opt_s; char * opt_s_1 = NULL; /* Working variables. */ size_t opt_s_size; struct sock_addr ** sas; size_t i; const char * ch; WARNP_INIT; /* We have no addresses to listen on yet. */ if ((opt_s = addrlist_init(0)) == NULL) { warnp("addrlist_init"); exit(1); } /* Parse the command line. */ while ((ch = GETOPT(argc, argv)) != NULL) { GETOPT_SWITCH(ch) { GETOPT_OPTARG("-n"): if (opt_n != 0) usage(); if (PARSENUM(&opt_n, optarg, 0, 65535)) { warn0("Invalid option: -n %s", optarg); usage(); } break; GETOPT_OPTARG("-p"): if (opt_p != NULL) usage(); if ((opt_p = strdup(optarg)) == NULL) OPT_EPARSE(ch, optarg); break; GETOPT_OPTARG("-s"): /* Keep a copy of the path for pidfile generation. */ if ((opt_s_1 == NULL) && ((opt_s_1 = strdup(optarg)) == NULL)) OPT_EPARSE(ch, optarg); /* Attempt to resolve to a list of addresses. */ if ((sas = sock_resolve(optarg)) == NULL) { warnp("Cannot resolve address: %s", optarg); exit(1); } if (sas[0] == NULL) { warn0("No addresses found for %s", optarg); exit(1); } /* Push pointers to addresses onto the list. */ for (i = 0; sas[i] != NULL; i++) { if (addrlist_append(opt_s, &sas[i], 1)) OPT_EPARSE(ch, optarg); } /* Free the array (but keep the addresses). */ free(sas); break; GETOPT_OPTARG("-t"): if (opt_t != NULL) usage(); if ((opt_t = strdup(optarg)) == NULL) OPT_EPARSE(ch, optarg); break; GETOPT_OPT("--version"): fprintf(stderr, "kivaloo-mux @VERSION@\n"); exit(0); GETOPT_MISSING_ARG: warn0("Missing argument to %s\n", ch); usage(); GETOPT_DEFAULT: warn0("illegal option -- %s\n", ch); usage(); } } argc -= optind; argv += optind; /* We should have processed all the arguments. */ if (argc != 0) usage(); /* Sanity-check options. */ if ((opt_s_size = addrlist_getsize(opt_s)) == 0) usage(); if (opt_t == NULL) usage(); /* Resolve target address. */ if ((sas = sock_resolve(opt_t)) == NULL) { warnp("Error resolving socket address: %s", opt_t); exit(1); } if (sas[0] == NULL) { warn0("No addresses found for %s", opt_t); exit(1); } /* Connect to the target. */ if ((sock_t = sock_connect(sas)) == -1) exit(1); /* Free the target address(es). */ sock_addr_freelist(sas); /* Create a queue of requests to the target. */ if ((Q_t = wire_requestqueue_init(sock_t)) == NULL) { warnp("Cannot create request queue"); exit(1); } /* Allocate array of source sockets. */ if ((socks_s = malloc(opt_s_size * sizeof(int))) == NULL) { warnp("malloc"); exit(1); } /* Create listening sockets. */ for (i = 0; i < opt_s_size; i++) { if ((socks_s[i] = sock_listener(*addrlist_get(opt_s, i))) == -1) exit(1); } /* Initialize the dispatcher. */ if ((dstate = dispatch_init(socks_s, opt_s_size, Q_t, opt_n ? (size_t)opt_n : SIZE_MAX)) == NULL) { warnp("Failed to initialize dispatcher"); exit(1); } /* Daemonize and write pid. */ if (opt_p == NULL) { if (asprintf(&opt_p, "%s.pid", opt_s_1) == -1) { warnp("asprintf"); exit(1); } } if (daemonize(opt_p)) { warnp("Failed to daemonize"); exit(1); } /* Loop until the dispatcher is finished. */ do { if (events_run()) { warnp("Error running event loop"); exit(1); } } while (dispatch_alive(dstate)); /* Clean up the dispatcher. */ dispatch_done(dstate); /* Shut down the request queue. */ wire_requestqueue_destroy(Q_t); wire_requestqueue_free(Q_t); /* Close sockets. */ for (i = 0; i < opt_s_size; i++) close(socks_s[i]); free(socks_s); close(sock_t); /* Free source socket addresses. */ for (i = 0; i < addrlist_getsize(opt_s); i++) sock_addr_free(*addrlist_get(opt_s, i)); addrlist_free(opt_s); /* Shut down the event subsystem. */ events_shutdown(); /* Free option strings. */ free(opt_p); free(opt_s_1); free(opt_t); /* Success! */ return (0); }
int main(int argc, char * argv[]) { /* State variables. */ struct serverpool * SP; struct dynamodb_request_queue * QW; struct dynamodb_request_queue * QR; struct dispatch_state * D; int s; /* Command-line parameters. */ char * opt_k = NULL; char * opt_l = NULL; char * opt_p = NULL; char * opt_r = NULL; char * opt_s = NULL; char * opt_t = NULL; int opt_1 = 0; /* Working variable. */ char * dynamodb_host; char * key_id; char * key_secret; struct sock_addr ** sas; struct logging_file * logfile; struct capacity_reader * M; const char * ch; WARNP_INIT; /* Parse the command line. */ while ((ch = GETOPT(argc, argv)) != NULL) { GETOPT_SWITCH(ch) { GETOPT_OPTARG("-k"): if (opt_k != NULL) usage(); if ((opt_k = strdup(optarg)) == NULL) OPT_EPARSE(ch, optarg); break; GETOPT_OPTARG("-l"): if (opt_l != NULL) usage(); if ((opt_l = strdup(optarg)) == NULL) OPT_EPARSE(ch, optarg); break; GETOPT_OPTARG("-p"): if (opt_p != NULL) usage(); if ((opt_p = strdup(optarg)) == NULL) OPT_EPARSE(ch, optarg); break; GETOPT_OPTARG("-r"): if (opt_r != NULL) usage(); if ((opt_r = strdup(optarg)) == NULL) OPT_EPARSE(ch, optarg); break; GETOPT_OPTARG("-s"): if (opt_s != NULL) usage(); if ((opt_s = strdup(optarg)) == NULL) OPT_EPARSE(ch, optarg); break; GETOPT_OPTARG("-t"): if (opt_t != NULL) usage(); if ((opt_t = strdup(optarg)) == NULL) OPT_EPARSE(ch, optarg); break; GETOPT_OPT("--version"): fprintf(stderr, "dynamodb-kv @VERSION@\n"); exit(0); GETOPT_OPT("-1"): if (opt_1 != 0) usage(); opt_1 = 1; break; GETOPT_MISSING_ARG: warn0("Missing argument to %s\n", ch); usage(); GETOPT_DEFAULT: warn0("illegal option -- %s\n", ch); usage(); } } argc -= optind; argv += optind; /* We should have processed all the arguments. */ if (argc != 0) usage(); /* Verify that we have mandatory options. */ if (opt_k == NULL) usage(); if (opt_r == NULL) usage(); if (opt_s == NULL) usage(); if (opt_t == NULL) usage(); /* Construct the DynamoDB endpoint host name. */ if (asprintf(&dynamodb_host, "dynamodb.%s.amazonaws.com:80", opt_r) == -1) { warnp("asprintf"); exit(1); } /* Start looking up addresses for DynamoDB endpoints. */ if ((SP = serverpool_create(dynamodb_host, 15, 120)) == NULL) { warnp("Error starting DNS lookups for %s", dynamodb_host); exit(1); } /* Read the key file. */ if (aws_readkeys(opt_k, &key_id, &key_secret)) { warnp("Error reading AWS keys from %s", opt_k); exit(1); } /* Create DynamoDB request queues for writes and reads. */ if ((QW = dynamodb_request_queue_init(key_id, key_secret, opt_r, SP)) == NULL) { warnp("Error creating DynamoDB request queue"); exit(1); } if ((QR = dynamodb_request_queue_init(key_id, key_secret, opt_r, SP)) == NULL) { warnp("Error creating DynamoDB request queue"); exit(1); } /* Start reading table throughput parameters. */ if ((M = capacity_init(key_id, key_secret, opt_t, opt_r, SP, QW, QR)) == NULL) { warnp("Error reading DynamoDB table metadata"); exit(1); } /* Resolve the listening address. */ if ((sas = sock_resolve(opt_s)) == NULL) { warnp("Error resolving socket address: %s", opt_s); exit(1); } if (sas[0] == NULL) { warn0("No addresses found for %s", opt_s); exit(1); } /* Create and bind a socket, and mark it as listening. */ if (sas[1] != NULL) warn0("Listening on first of multiple addresses found for %s", opt_s); if ((s = sock_listener(sas[0])) == -1) exit(1); /* If requested, create a log file. */ if (opt_l != NULL) { if ((logfile = logging_open(opt_l)) == NULL) { warnp("Cannot open log file"); exit(1); } dynamodb_request_queue_log(QW, logfile); dynamodb_request_queue_log(QR, logfile); } else { logfile = NULL; } /* Daemonize and write pid. */ if (opt_p == NULL) { if (asprintf(&opt_p, "%s.pid", opt_s) == -1) { warnp("asprintf"); exit(1); } } if (daemonize(opt_p)) { warnp("Failed to daemonize"); exit(1); } /* Handle connections, one at once. */ do { /* accept a connection. */ if ((D = dispatch_accept(QW, QR, opt_t, s)) == NULL) { warnp("Error accepting new connection"); exit(1); } /* Loop until the connection dies. */ do { if (events_run()) { warnp("Error running event loop"); exit(1); } } while (dispatch_alive(D)); /* Clean up the connection. */ if (dispatch_done(D)) exit(1); } while (opt_1 == 0); /* Close the log file, if we have one. */ if (logfile != NULL) logging_close(logfile); /* Close the listening socket. */ close(s); /* Free the address structures. */ sock_addr_freelist(sas); /* Stop performing DescribeTable requests. */ capacity_free(M); /* Free DynamoDB request queues. */ dynamodb_request_queue_free(QR); dynamodb_request_queue_free(QW); /* Stop DNS lookups. */ serverpool_free(SP); /* Shut down the event subsystem. */ events_shutdown(); /* Free string allocated by asprintf. */ free(dynamodb_host); /* Free key strings. */ free(key_id); insecure_memzero(key_secret, strlen(key_secret)); free(key_secret); /* Free option strings. */ free(opt_k); free(opt_l); free(opt_p); free(opt_r); free(opt_s); free(opt_t); /* Success! */ exit(0); }
static void netproto_connect_atexit(void) { sock_addr_freelist(srv_addr); }
int main(int argc, char * argv[]) { /* Command-line parameters. */ int opt_f = 0; int opt_g = 0; int opt_j = 0; const char * opt_k = NULL; int opt_o_set = 0; double opt_o = 0.0; const char * opt_t = NULL; /* Working variables. */ struct sock_addr ** sas_t; struct proto_secret * K; const char * ch; int s[2]; int conndone = 0; void * conn_cookie; WARNP_INIT; /* Parse the command line. */ while ((ch = GETOPT(argc, argv)) != NULL) { GETOPT_SWITCH(ch) { GETOPT_OPT("-f"): if (opt_f) usage(); opt_f = 1; break; GETOPT_OPT("-g"): if (opt_g) usage(); opt_g = 1; break; GETOPT_OPT("-j"): if (opt_j) usage(); opt_j = 1; break; GETOPT_OPTARG("-k"): if (opt_k) usage(); opt_k = optarg; break; GETOPT_OPTARG("-o"): if (opt_o_set) usage(); opt_o_set = 1; if (PARSENUM(&opt_o, optarg, 0, INFINITY)) OPT_EPARSE(ch, optarg); break; GETOPT_OPTARG("-t"): if (opt_t) usage(); opt_t = optarg; break; GETOPT_OPT("-v"): fprintf(stderr, "spipe @VERSION@\n"); exit(0); GETOPT_MISSING_ARG: warn0("Missing argument to %s", ch); usage(); GETOPT_DEFAULT: warn0("illegal option -- %s", ch); usage(); } } argc -= optind; argv += optind; /* We should have processed all the arguments. */ if (argc != 0) usage(); (void)argv; /* argv is not used beyond this point. */ /* Set defaults. */ if (opt_o == 0.0) opt_o = 5.0; /* Sanity-check options. */ if (opt_f && opt_g) usage(); if (opt_k == NULL) usage(); if (!(opt_o > 0.0)) usage(); if (opt_t == NULL) usage(); /* Resolve target address. */ if ((sas_t = sock_resolve(opt_t)) == NULL) { warnp("Error resolving socket address: %s", opt_t); goto err0; } if (sas_t[0] == NULL) { warn0("No addresses found for %s", opt_t); goto err1; } /* Load the keying data. */ if ((K = proto_crypt_secret(opt_k)) == NULL) { warnp("Error reading shared secret"); goto err1; } /* * Create a socket pair to push bits through. The spiped protocol * code expects to be handed a socket to read/write bits to, and our * stdin/stdout might not be sockets (in fact, almost certainly aren't * sockets); so we'll hand one end of the socket pair to the spiped * protocol code and shuttle bits between stdin/stdout and the other * end of the socket pair ourselves. */ if (socketpair(AF_UNIX, SOCK_STREAM, 0, s)) { warnp("socketpair"); goto err2; } /* Set up a connection. */ if ((conn_cookie = proto_conn_create(s[1], sas_t, 0, opt_f, opt_g, opt_j, K, opt_o, callback_conndied, &conndone)) == NULL) { warnp("Could not set up connection"); goto err2; } /* Push bits from stdin into the socket. */ if (pushbits(STDIN_FILENO, s[0])) { warnp("Could not push bits"); goto err3; } /* Push bits from the socket to stdout. */ if (pushbits(s[0], STDOUT_FILENO)) { warnp("Could not push bits"); goto err3; } /* Loop until we're done with the connection. */ if (events_spin(&conndone)) { warnp("Error running event loop"); exit(1); } /* Clean up. */ events_shutdown(); free(K); /* Success! */ exit(0); err3: proto_conn_drop(conn_cookie); sas_t = NULL; events_shutdown(); err2: free(K); err1: sock_addr_freelist(sas_t); err0: /* Failure! */ exit(1); }
int main(int argc, char * argv[]) { struct sock_addr ** sas; int s; struct wire_requestqueue * Q; char ** keys; size_t i; WARNP_INIT; /* Check number of arguments. */ if (argc != 2) { fprintf(stderr, "usage: tokyo %s\n", "<socketname>"); exit(1); } /* Resolve the socket address and connect. */ if ((sas = sock_resolve(argv[1])) == NULL) { warnp("Error resolving socket address: %s", argv[1]); exit(1); } if (sas[0] == NULL) { warn0("No addresses found for %s", argv[1]); exit(1); } if ((s = sock_connect(sas)) == -1) exit(1); /* Create a request queue. */ if ((Q = wire_requestqueue_init(s)) == NULL) { warnp("Cannot create packet write queue"); exit(1); } /* Create keys. */ if ((keys = malloc(1000000 * sizeof(char *))) == NULL) { warnp("malloc"); exit(1); } for (i = 0; i < 1000000; i++) { if (asprintf(&keys[i], "%08zu", i) == -1) { warnp("asprintf"); exit(1); } } /* Run benchmark. */ if (tokyo(Q, keys)) exit(1); /* Free keys. */ for (i = 0; i < 1000000; i++) free(keys[i]); free(keys); /* Free the request queue. */ wire_requestqueue_destroy(Q); wire_requestqueue_free(Q); /* Free socket addresses. */ sock_addr_freelist(sas); /* Shut down the event subsystem. */ events_shutdown(); /* Success! */ exit(0); }