Beispiel #1
0
/**
 * Wraps the actual implementation, which has to return a value as part of the threaded implementation.
 */
int system_sleep_pin(uint16_t wakeUpPin, uint16_t edgeTriggerMode, long seconds, uint32_t param, void* reserved)
{
    // Cancel current connection attempt to unblock the system thread
    network_connect_cancel(0, 1, 0, 0);
    InterruptMode m = (InterruptMode)edgeTriggerMode;
    return system_sleep_pin_impl(&wakeUpPin, 1, &m, 1, seconds, param, reserved);
}
Beispiel #2
0
/**
 * proto_conn_create(s, sas, decr, nopfs, requirepfs, nokeepalive, K, timeo,
 *     callback_dead, cookie):
 * Create a connection with one end at ${s} and the other end connecting to
 * the target addresses ${sas}.  If ${decr} is 0, encrypt the outgoing data;
 * if ${decr} is nonzero, decrypt the incoming data.  If ${nopfs} is non-zero,
 * don't use perfect forward secrecy.  If ${requirepfs} is non-zero, drop
 * the connection if the other end tries to disable perfect forward secrecy.
 * Enable transport layer keep-alives (if applicable) on both sockets if and
 * only if ${nokeepalive} is zero.  Drop the connection if the handshake or
 * connecting to the target takes more than ${timeo} seconds.  When the
 * connection is dropped, invoke ${callback_dead}(${cookie}).  Free ${sas}
 * once it is no longer needed.  Return a cookie which can be passed to
 * proto_conn_drop.
 */
void *
proto_conn_create(int s, struct sock_addr ** sas, int decr, int nopfs,
    int requirepfs, int nokeepalive, const struct proto_secret * K,
    double timeo, int (* callback_dead)(void *), void * cookie)
{
	struct conn_state * C;

	/* Bake a cookie for this connection. */
	if ((C = malloc(sizeof(struct conn_state))) == NULL)
		goto err0;
	C->callback_dead = callback_dead;
	C->cookie = cookie;
	C->sas = sas;
	C->decr = decr;
	C->nopfs = nopfs;
	C->requirepfs = requirepfs;
	C->nokeepalive = nokeepalive;
	C->K = K;
	C->timeo = timeo;
	C->s = s;
	C->t = -1;
	C->connect_cookie = NULL;
	C->connect_timeout_cookie = NULL;
	C->handshake_cookie = NULL;
	C->handshake_timeout_cookie = NULL;
	C->k_f = C->k_r = NULL;
	C->pipe_f = C->pipe_r = NULL;
	C->stat_f = C->stat_r = 1;

	/* Start the connect timer. */
	if ((C->connect_timeout_cookie = events_timer_register_double(
	    callback_connect_timeout, C, C->timeo)) == NULL)
		goto err1;

	/* Connect to target. */
	if ((C->connect_cookie =
	    network_connect(C->sas, callback_connect_done, C)) == NULL)
		goto err2;

	/* If we're decrypting, start the handshake. */
	if (C->decr) {
		if (starthandshake(C, C->s, C->decr))
			goto err3;
	}

	/* Success! */
	return (C);

err3:
	network_connect_cancel(C->connect_cookie);
err2:
	events_timer_cancel(C->connect_timeout_cookie);
err1:
	free(C);
err0:
	/* Failure! */
	return (NULL);
}
Beispiel #3
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);
}
Beispiel #4
0
/**
 * 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);
}
Beispiel #5
0
/* Drop a connection. */
static int
dropconn(struct conn_state * C)
{
	int rc = 0;

	/* Close the incoming connection. */
	C->A->nconn -= 1;
	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);

	/* 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. */
	pcrypt_free(C->k_f);
	pcrypt_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);

	/* Accept more connections if we need to. */
	if (doaccept(C->A))
		rc = -1;

	/* Free the connection cookie. */
	free(C);

	/* Return success/fail status. */
	return (rc);
}
Beispiel #6
0
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);
}
Beispiel #7
0
/* Handle an incoming connection. */
static int
callback_gotconn(void * cookie, int s)
{
	struct accept_state * A = cookie;
	struct conn_state * C;

	/* This accept is no longer in progress. */
	A->accept_cookie = NULL;

	/* We have gained a connection. */
	A->nconn += 1;

	/* Bake a cookie for this connection. */
	if ((C = malloc(sizeof(struct conn_state))) == NULL)
		goto err1;
	C->A = A;
	C->s = s;
	C->t = -1;
	C->connect_cookie = NULL;
	C->handshake_cookie = NULL;
	C->connect_timeout_cookie = C->handshake_timeout_cookie = NULL;
	C->k_f = C->k_r = NULL;
	C->pipe_f = C->pipe_r = NULL;
	C->stat_f = C->stat_r = 1;

	/* Start the connect timer. */
	if ((C->connect_timeout_cookie = events_timer_register_double(
	    callback_connect_timeout, C, C->A->timeo)) == NULL)
		goto err2;

	/* Connect to target. */
	if ((C->connect_cookie =
	    network_connect(A->sas, callback_connect_done, C)) == NULL)
		goto err3;

	/* If we're decrypting, start the handshake. */
	if (C->A->decr) {
		if (starthandshake(C, C->s, C->A->decr))
			goto err4;
	}

	/* Accept another connection if we can. */
	if (doaccept(A))
		goto err0;

	/* Success! */
	return (0);

err4:
	network_connect_cancel(C->connect_cookie);
err3:
	events_timer_cancel(C->connect_timeout_cookie);
err2:
	free(C);
err1:
	A->nconn -= 1;
	close(s);
err0:
	/* Failure! */
	return (-1);
}
Beispiel #8
0
int system_sleep_pins(const uint16_t* pins, size_t pins_count, const InterruptMode* modes, size_t modes_count, long seconds, uint32_t param, void* reserved)
{
    network_connect_cancel(0, 1, 0, 0);
    return system_sleep_pin_impl(pins, pins_count, modes, modes_count, seconds, param, reserved);
}
Beispiel #9
0
int system_sleep(Spark_Sleep_TypeDef sleepMode, long seconds, uint32_t param, void* reserved)
{
    network_connect_cancel(0, 1, 0, 0);
    return system_sleep_impl(sleepMode, seconds, param, reserved);
}