예제 #1
0
/* Save and check signature. */
static Pkt *check_and_save_commit_sig(struct peer *peer,
				      struct commit_info *ci,
				      const Signature *pb)
{
	struct bitcoin_signature *sig = tal(ci, struct bitcoin_signature);

	assert(!ci->sig);
	sig->stype = SIGHASH_ALL;
	if (!proto_to_signature(peer->dstate->secpctx, pb, &sig->sig))
		return pkt_err(peer, "Malformed signature");

	log_debug(peer->log, "Checking sig for %u/%u msatoshis, %zu/%zu htlcs",
		  ci->cstate->side[OURS].pay_msat,
		  ci->cstate->side[THEIRS].pay_msat,
		  tal_count(ci->cstate->side[OURS].htlcs),
		  tal_count(ci->cstate->side[THEIRS].htlcs));

	/* Their sig should sign our commit tx. */
	if (!check_tx_sig(peer->dstate->secpctx,
			  ci->tx, 0,
			  NULL, 0,
			  peer->anchor.witnessscript,
			  &peer->remote.commitkey,
			  sig))
		return pkt_err(peer, "Bad signature");

	ci->sig = sig;
	return NULL;
}
예제 #2
0
파일: packets.c 프로젝트: dooglus/lightning
static Pkt *find_commited_htlc(struct peer *peer, uint64_t id,
			       size_t *n_us, size_t *n_them)
{
	/* BOLT #2:
	 *
	 * A node MUST check that `id` corresponds to an HTLC in its
	 * current commitment transaction, and MUST fail the
	 * connection if it does not.
	 */
	*n_us = funding_htlc_by_id(&peer->us.commit->cstate->a, id);
	if (*n_us == tal_count(peer->us.commit->cstate->a.htlcs))
		return pkt_err(peer, "Did not find HTLC %"PRIu64, id);

	/* They must not fail/fulfill twice, so it should be in staging, too. */
	*n_us = funding_htlc_by_id(&peer->us.staging_cstate->a, id);
	if (*n_us == tal_count(peer->us.staging_cstate->a.htlcs))
		return pkt_err(peer, "Already removed HTLC %"PRIu64, id);

	/* FIXME: Assert this... */
	/* Note: these should match. */
	*n_them = funding_htlc_by_id(&peer->them.staging_cstate->b, id);
	if (*n_them == tal_count(peer->them.staging_cstate->b.htlcs))
		return pkt_err(peer, "Did not find your HTLC %"PRIu64, id);

	return NULL;
}
예제 #3
0
/* Process various packets: return an error packet on failure. */
Pkt *accept_pkt_open(struct peer *peer, const Pkt *pkt)
{
	struct rel_locktime locktime;
	const OpenChannel *o = pkt->open;

	if (!proto_to_rel_locktime(o->delay, &locktime))
		return pkt_err(peer, "Invalid delay");
	if (o->delay->locktime_case != LOCKTIME__LOCKTIME_BLOCKS)
		return pkt_err(peer, "Delay in seconds not accepted");
	if (o->delay->blocks > peer->dstate->config.locktime_max)
		return pkt_err(peer, "Delay too great");
	if (o->min_depth > peer->dstate->config.anchor_confirms_max)
		return pkt_err(peer, "min_depth too great");
	if (o->initial_fee_rate < peer->dstate->config.commitment_fee_rate_min)
		return pkt_err(peer, "Commitment fee rate too low");
	if (o->anch == OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR)
		peer->remote.offer_anchor = CMD_OPEN_WITH_ANCHOR;
	else if (o->anch == OPEN_CHANNEL__ANCHOR_OFFER__WONT_CREATE_ANCHOR)
		peer->remote.offer_anchor = CMD_OPEN_WITHOUT_ANCHOR;
	else
		return pkt_err(peer, "Unknown offer anchor value");

	if (peer->remote.offer_anchor == peer->local.offer_anchor)
		return pkt_err(peer, "Only one side can offer anchor");

	if (!proto_to_rel_locktime(o->delay, &peer->remote.locktime))
		return pkt_err(peer, "Malformed locktime");
	peer->remote.mindepth = o->min_depth;
	peer->remote.commit_fee_rate = o->initial_fee_rate;
	if (!proto_to_pubkey(peer->dstate->secpctx,
			     o->commit_key, &peer->remote.commitkey))
		return pkt_err(peer, "Bad commitkey");
	if (!proto_to_pubkey(peer->dstate->secpctx,
			     o->final_key, &peer->remote.finalkey))
		return pkt_err(peer, "Bad finalkey");

	/* Set up their commit info now: rest gets done in setup_first_commit
	 * once anchor is established. */
	peer->remote.commit = new_commit_info(peer);
	proto_to_sha256(o->revocation_hash, &peer->remote.commit->revocation_hash);
	proto_to_sha256(o->next_revocation_hash,
			&peer->remote.next_revocation_hash);

	/* Witness script for anchor. */
	peer->anchor.witnessscript
		= bitcoin_redeem_2of2(peer, peer->dstate->secpctx,
				      &peer->local.commitkey,
				      &peer->remote.commitkey);
	return NULL;
}
예제 #4
0
Pkt *accept_pkt_revocation(struct peer *peer, const Pkt *pkt)
{
	const UpdateRevocation *r = pkt->update_revocation;
	struct commit_info *ci = peer->remote.commit->prev;

	/* BOLT #2:
	 *
	 * The receiver of `update_revocation` MUST check that the
	 * SHA256 hash of `revocation_preimage` matches the previous commitment
	 * transaction, and MUST fail if it does not.
	 */
	if (!check_preimage(r->revocation_preimage, &ci->revocation_hash))
		return pkt_err(peer, "complete preimage incorrect");

	/* They're revoking the previous one. */
	assert(!ci->revocation_preimage);
	ci->revocation_preimage = tal(ci, struct sha256);

	proto_to_sha256(r->revocation_preimage, ci->revocation_preimage);

	// save revocation preimages in shachain
	if (!shachain_add_hash(&peer->their_preimages, 0xFFFFFFFFFFFFFFFFL - ci->commit_num, ci->revocation_preimage))
		return pkt_err(peer, "preimage not next in shachain");

	/* Save next revocation hash. */
	proto_to_sha256(r->next_revocation_hash,
			&peer->remote.next_revocation_hash);

	/* BOLT #2:
	 *
	 * The receiver of `update_revocation`... MUST add the remote
	 * unacked changes to the set of local acked changes.
	 */
	add_acked_changes(&peer->local.commit->acked_changes, ci->unacked_changes);
	apply_changeset(peer, &peer->local, OURS,
			ci->unacked_changes,
			tal_count(ci->unacked_changes));

	/* Should never examine these again. */
	ci->unacked_changes = tal_free(ci->unacked_changes);

	/* That revocation has committed them to changes in the current commitment.
	 * Any acked changes come from our commitment, so those are now committed
	 * by both of us.
	 */
	peer_both_committed_to(peer, ci->acked_changes, THEIRS);
	
	return NULL;
}
예제 #5
0
파일: packets.c 프로젝트: dooglus/lightning
Pkt *accept_pkt_htlc_fulfill(struct peer *peer, const Pkt *pkt)
{
	const UpdateFulfillHtlc *f = pkt->update_fulfill_htlc;
	size_t n_us, n_them;
	struct sha256 r, rhash;
	Pkt *err;

	err = find_commited_htlc(peer, f->id, &n_us, &n_them);
	if (err)
		return err;

	/* Now, it must solve the HTLC rhash puzzle. */
	proto_to_sha256(f->r, &r);
	sha256(&rhash, &r, sizeof(r));

	if (!structeq(&rhash, &peer->us.staging_cstate->a.htlcs[n_us].rhash))
		return pkt_err(peer, "Invalid r for %"PRIu64, f->id);

	/* Same ID must have same rhash */
	assert(structeq(&rhash, &peer->them.staging_cstate->b.htlcs[n_them].rhash));

	funding_a_fulfill_htlc(peer->us.staging_cstate, n_us);
	funding_b_fulfill_htlc(peer->them.staging_cstate, n_them);
	return NULL;
}
예제 #6
0
파일: packets.c 프로젝트: dooglus/lightning
void queue_pkt_anchor(struct peer *peer)
{
	OpenAnchor *a = tal(peer, OpenAnchor);

	open_anchor__init(a);
	a->txid = sha256_to_proto(a, &peer->anchor.txid.sha);
	a->output_index = peer->anchor.index;
	a->amount = peer->anchor.satoshis;

	/* This shouldn't happen! */
	if (!setup_first_commit(peer)) {
		queue_pkt_err(peer,
			      pkt_err(peer,
				      "Own anchor has insufficient funds"));
		return;
	}

	/* Sign their commit sig */
	peer->them.commit->sig = tal(peer->them.commit,
				     struct bitcoin_signature);
	peer->them.commit->sig->stype = SIGHASH_ALL;
	peer_sign_theircommit(peer, peer->them.commit->tx,
			      &peer->them.commit->sig->sig);
	a->commit_sig = signature_to_proto(a, &peer->them.commit->sig->sig);

	queue_pkt(peer, PKT__PKT_OPEN_ANCHOR, a);
}
예제 #7
0
static Pkt *find_commited_htlc(struct peer *peer, uint64_t id,
			       struct htlc **local_htlc)
{
	/* BOLT #2:
	 *
	 * A node MUST check that `id` corresponds to an HTLC in its
	 * current commitment transaction, and MUST fail the
	 * connection if it does not.
	 */
	if (!cstate_htlc_by_id(peer->local.commit->cstate, id, OURS))
		return pkt_err(peer, "Did not find HTLC %"PRIu64, id);

	/* They must not fail/fulfill twice, so it should be in staging, too. */
	*local_htlc = cstate_htlc_by_id(peer->local.staging_cstate, id, OURS);
	if (!*local_htlc)
		return pkt_err(peer, "Already removed HTLC %"PRIu64, id);

	return NULL;
}
예제 #8
0
파일: packets.c 프로젝트: dooglus/lightning
/* Save and check signature. */
static Pkt *check_and_save_commit_sig(struct peer *peer,
				      struct commit_info *ci,
				      const Signature *pb)
{
	assert(!ci->sig);
	ci->sig = tal(ci, struct bitcoin_signature);
	ci->sig->stype = SIGHASH_ALL;
	if (!proto_to_signature(pb, &ci->sig->sig))
		return pkt_err(peer, "Malformed signature");

	/* Their sig should sign our commit tx. */
	if (!check_tx_sig(peer->dstate->secpctx,
			  ci->tx, 0,
			  NULL, 0,
			  peer->anchor.witnessscript,
			  &peer->them.commitkey,
			  ci->sig))
		return pkt_err(peer, "Bad signature");

	return NULL;
}
예제 #9
0
Pkt *accept_pkt_commit(struct peer *peer, const Pkt *pkt)
{
	const UpdateCommit *c = pkt->update_commit;
	Pkt *err;
	struct commit_info *ci = new_commit_info(peer);

	/* Create new commit info for this commit tx. */
	ci->prev = peer->local.commit;
	ci->commit_num = ci->prev->commit_num + 1;
	ci->revocation_hash = peer->local.next_revocation_hash;

	/* BOLT #2:
	 *
	 * A receiving node MUST apply all local acked and unacked
	 * changes except unacked fee changes to the local commitment
	 */
	/* (We already applied them to staging_cstate as we went) */
	ci->cstate = copy_cstate(ci, peer->local.staging_cstate);
	ci->tx = create_commit_tx(ci, peer->dstate->secpctx,
				  &peer->local.finalkey,
				  &peer->remote.finalkey,
				  &peer->local.locktime,
				  &peer->remote.locktime,
				  &peer->anchor.txid,
				  peer->anchor.index,
				  peer->anchor.satoshis,
				  &ci->revocation_hash,
				  ci->cstate,
				  OURS,
				  &ci->map);

	/* BOLT #2:
	 *
	 * A node MUST NOT send an `update_commit` message which does
	 * not include any updates.
	 */
	if (ci->prev->cstate->changes == ci->cstate->changes)
		return pkt_err(peer, "Empty commit");

	err = check_and_save_commit_sig(peer, ci, c->sig);
	if (err)
		return err;

	/* Switch to the new commitment. */
	peer->local.commit = ci;
	peer_get_revocation_hash(peer, ci->commit_num + 1,
				 &peer->local.next_revocation_hash);

	return NULL;
}
예제 #10
0
Pkt *accept_pkt_anchor(struct peer *peer, const Pkt *pkt)
{
	const OpenAnchor *a = pkt->open_anchor;

	/* They must be offering anchor for us to try accepting */
	assert(peer->local.offer_anchor == CMD_OPEN_WITHOUT_ANCHOR);
	assert(peer->remote.offer_anchor == CMD_OPEN_WITH_ANCHOR);

	proto_to_sha256(a->txid, &peer->anchor.txid.sha);
	peer->anchor.index = a->output_index;
	peer->anchor.satoshis = a->amount;

	if (!setup_first_commit(peer))
		return pkt_err(peer, "Insufficient funds for fee");

	return NULL;
}
예제 #11
0
void queue_pkt_anchor(struct peer *peer)
{
	OpenAnchor *a = tal(peer, OpenAnchor);

	open_anchor__init(a);
	a->txid = sha256_to_proto(a, &peer->anchor.txid.sha);
	a->output_index = peer->anchor.index;
	a->amount = peer->anchor.satoshis;

	/* This shouldn't happen! */
	if (!setup_first_commit(peer)) {
		queue_pkt_err(peer,
			      pkt_err(peer,
				      "Own anchor has insufficient funds"));
		return;
	}

	queue_pkt(peer, PKT__PKT_OPEN_ANCHOR, a);
}
예제 #12
0
파일: packets.c 프로젝트: dooglus/lightning
Pkt *accept_pkt_commit(struct peer *peer, const Pkt *pkt)
{
	const UpdateCommit *c = pkt->update_commit;
	Pkt *err;
	struct commit_info *ci = talz(peer, struct commit_info);

	/* Create new commit info for this commit tx. */
	ci->prev = peer->us.commit;
	ci->revocation_hash = peer->us.next_revocation_hash;
	ci->cstate = copy_funding(ci, peer->us.staging_cstate);
	ci->tx = create_commit_tx(ci,
				  &peer->us.finalkey,
				  &peer->them.finalkey,
				  &peer->them.locktime,
				  &peer->anchor.txid,
				  peer->anchor.index,
				  peer->anchor.satoshis,
				  &ci->revocation_hash,
				  ci->cstate);

	/* BOLT #2:
	 *
	 * A node MUST NOT send an `update_commit` message which does
	 * not include any updates.
	 */
	if (ci->prev->cstate->changes == ci->cstate->changes)
		return pkt_err(peer, "Empty commit");
			
	err = check_and_save_commit_sig(peer, ci, c->sig);
	if (err)
		return err;

	/* Switch to the new commitment. */
	peer->us.commit = ci;
	peer->commit_tx_counter++;
	peer_get_revocation_hash(peer, peer->commit_tx_counter + 1,
				 &peer->us.next_revocation_hash);
	return NULL;
}
예제 #13
0
파일: packets.c 프로젝트: dooglus/lightning
Pkt *accept_pkt_revocation(struct peer *peer, const Pkt *pkt)
{
	const UpdateRevocation *r = pkt->update_revocation;

	/* FIXME: Save preimage in shachain too. */
	if (!check_preimage(r->revocation_preimage,
			    &peer->them.commit->prev->revocation_hash))
		return pkt_err(peer, "complete preimage incorrect");

	/* They're revoking the previous one. */
	assert(!peer->them.commit->prev->revocation_preimage);
	peer->them.commit->prev->revocation_preimage
		= tal(peer->them.commit->prev, struct sha256);

	proto_to_sha256(r->revocation_preimage,
			peer->them.commit->prev->revocation_preimage);

	/* Save next revocation hash. */
	proto_to_sha256(r->next_revocation_hash,
			&peer->them.next_revocation_hash);

	return NULL;
}
예제 #14
0
Pkt *accept_pkt_htlc_fulfill(struct peer *peer, const Pkt *pkt)
{
	const UpdateFulfillHtlc *f = pkt->update_fulfill_htlc;
	struct htlc *htlc;
	struct sha256 rhash;
	struct rval r;
	Pkt *err;
	union htlc_staging stage;

	err = find_commited_htlc(peer, f->id, &htlc);
	if (err)
		return err;

	/* Now, it must solve the HTLC rhash puzzle. */
	proto_to_rval(f->r, &r);
	sha256(&rhash, &r, sizeof(r));

	if (!structeq(&rhash, &htlc->rhash))
		return pkt_err(peer, "Invalid r for %"PRIu64, f->id);

	/* We can relay this upstream immediately. */
	our_htlc_fulfilled(peer, htlc, &r);

	/* BOLT #2:
	 *
	 * ... and the receiving node MUST add the HTLC fulfill/fail
	 * to the unacked changeset for its local commitment.
	 */
	cstate_fulfill_htlc(peer->local.staging_cstate, htlc, OURS);

	stage.fulfill.fulfill = HTLC_FULFILL;
	stage.fulfill.htlc = htlc;
	stage.fulfill.r = r;
	add_unacked(&peer->local, &stage);
	return NULL;
}
예제 #15
0
파일: packets.c 프로젝트: dooglus/lightning
/*
 * We add changes to both our staging cstate (as they did when they sent
 * it) and theirs (as they will when we ack it).
 */
Pkt *accept_pkt_htlc_add(struct peer *peer, const Pkt *pkt)
{
	const UpdateAddHtlc *u = pkt->update_add_htlc;
	struct sha256 rhash;
	struct abs_locktime expiry;

	/* BOLT #2:
	 *
	 * `amount_msat` MUST BE greater than 0.
	 */
	if (u->amount_msat == 0)
		return pkt_err(peer, "Invalid amount_msat");

	proto_to_sha256(u->r_hash, &rhash);
	if (!proto_to_abs_locktime(u->expiry, &expiry))
		return pkt_err(peer, "Invalid HTLC expiry");

	/* FIXME: Handle block-based expiry! */
	if (!abs_locktime_is_seconds(&expiry))
		return pkt_err(peer, "HTLC expiry in blocks not supported!");

	/* BOLT #2:
	 *
	 * A node MUST NOT add a HTLC if it would result in it
	 * offering more than 1500 HTLCs in either commitment transaction.
	 */
	if (tal_count(peer->them.staging_cstate->a.htlcs) == 1500
	    || tal_count(peer->us.staging_cstate->b.htlcs) == 1500)
		return pkt_err(peer, "Too many HTLCs");

	/* BOLT #2:
	 *
	 * A node MUST NOT set `id` equal to another HTLC which is in
	 * the current staged commitment transaction.
	 */
	if (funding_htlc_by_id(&peer->them.staging_cstate->a, u->id)
	    < tal_count(peer->them.staging_cstate->a.htlcs))
		return pkt_err(peer, "HTLC id %"PRIu64" clashes for you", u->id);

	/* FIXME: Assert this... */
	/* Note: these should be in sync, so this should be redundant! */
	if (funding_htlc_by_id(&peer->us.staging_cstate->b, u->id)
	    < tal_count(peer->us.staging_cstate->b.htlcs))
		return pkt_err(peer, "HTLC id %"PRIu64" clashes for us", u->id);

	/* BOLT #2:
	 *
	 * A node MUST NOT offer `amount_msat` it cannot pay for in
	 * both commitment transactions at the current `fee_rate` (see
	 * "Fee Calculation" ).  A node SHOULD fail the connection if
	 * this occurs.
	 */

	/* FIXME: This is wrong!  We may have already added more txs to
	 * them.staging_cstate, driving that fee up.
	 * We should check against the last version they acknowledged. */
	if (!funding_a_add_htlc(peer->them.staging_cstate,
				u->amount_msat, &expiry, &rhash, u->id))
		return pkt_err(peer, "Cannot afford %"PRIu64" milli-satoshis"
			       " in your commitment tx",
			       u->amount_msat);

	/* If we fail here, we've already changed them.staging_cstate, so
	 * MUST terminate. */
	if (!funding_b_add_htlc(peer->us.staging_cstate,
				u->amount_msat, &expiry, &rhash, u->id))
		return pkt_err(peer, "Cannot afford %"PRIu64" milli-satoshis"
			       " in our commitment tx",
			       u->amount_msat);

	peer_add_htlc_expiry(peer, &expiry);

	/* FIXME: Fees must be sufficient. */
	return NULL;
}
예제 #16
0
/*
 * We add changes to both our staging cstate (as they did when they sent
 * it) and theirs (as they will when we ack it).
 */
Pkt *accept_pkt_htlc_add(struct peer *peer, const Pkt *pkt)
{
	const UpdateAddHtlc *u = pkt->update_add_htlc;
	struct sha256 rhash;
	struct abs_locktime expiry;
	struct htlc *htlc;
	union htlc_staging stage;

	/* BOLT #2:
	 *
	 * `amount_msat` MUST BE greater than 0.
	 */
	if (u->amount_msat == 0)
		return pkt_err(peer, "Invalid amount_msat");

	proto_to_sha256(u->r_hash, &rhash);
	if (!proto_to_abs_locktime(u->expiry, &expiry))
		return pkt_err(peer, "Invalid HTLC expiry");

	if (abs_locktime_is_seconds(&expiry))
		return pkt_err(peer, "HTLC expiry in seconds not supported!");

	/* BOLT #2:
	 *
	 * A node MUST NOT add a HTLC if it would result in it
	 * offering more than 300 HTLCs in the remote commitment transaction.
	 */
	if (tal_count(peer->remote.staging_cstate->side[THEIRS].htlcs) == 300)
		return pkt_err(peer, "Too many HTLCs");

	/* BOLT #2:
	 *
	 * A node MUST set `id` to a unique identifier for this HTLC
	 * amongst all past or future `update_add_htlc` messages.
	 */
	/* Note that it's not *our* problem if they do this, it's
	 * theirs (future confusion).  Nonetheless, we detect and
	 * error for them. */
	if (htlc_map_get(&peer->remote.htlcs, u->id))
		return pkt_err(peer, "HTLC id %"PRIu64" clashes for you", u->id);

	/* BOLT #2:
	 *
	 * ...and the receiving node MUST add the HTLC addition to the
	 * unacked changeset for its local commitment. */
	htlc = peer_new_htlc(peer, u->id, u->amount_msat, &rhash,
			     abs_locktime_to_blocks(&expiry),
			     u->route->info.data, u->route->info.len,
			     NULL, THEIRS);

	/* BOLT #2:
	 *
	 * A node MUST NOT offer `amount_msat` it cannot pay for in
	 * the remote commitment transaction at the current `fee_rate` (see
	 * "Fee Calculation" ).  A node SHOULD fail the connection if
	 * this occurs.
	 */
	if (!cstate_add_htlc(peer->local.staging_cstate, htlc, THEIRS)) {
		tal_free(htlc);
		return pkt_err(peer, "Cannot afford %"PRIu64" milli-satoshis"
			       " in our commitment tx",
			       u->amount_msat);
	}

	stage.add.add = HTLC_ADD;
	stage.add.htlc = htlc;
	add_unacked(&peer->local, &stage);

	return NULL;
}
예제 #17
0
파일: packets.c 프로젝트: dooglus/lightning
Pkt *accept_pkt_close_sig(struct peer *peer, const Pkt *pkt, bool *acked,
			  bool *we_agree)
{
	const CloseSignature *c = pkt->close_signature;
	struct bitcoin_tx *close_tx;
	struct bitcoin_signature theirsig;

	log_info(peer->log, "accept_pkt_close_sig: they offered close fee %"
		 PRIu64, c->close_fee);
	*acked = *we_agree = false;

	/* BOLT #2:
	 *
	 * The sender MUST set `close_fee` lower than or equal to the fee of the
	 * final commitment transaction, and MUST set `close_fee` to an even
	 * number of satoshis.
	 */
	if ((c->close_fee & 1)
	    || c->close_fee > commit_tx_fee(peer->them.commit->tx,
					    peer->anchor.satoshis)) {
		return pkt_err(peer, "Invalid close fee");
	}

	/* FIXME: Don't accept tiny fee at all? */

	/* BOLT #2:
	   ... otherwise it SHOULD propose a
	   value strictly between the received `close_fee` and its
	   previously-sent `close_fee`.
	*/
	if (peer->closing.their_sig) {
		/* We want more, they should give more. */
		if (peer->closing.our_fee > peer->closing.their_fee) {
			if (c->close_fee <= peer->closing.their_fee)
				return pkt_err(peer, "Didn't increase close fee");
		} else {
			if (c->close_fee >= peer->closing.their_fee)
				return pkt_err(peer, "Didn't decrease close fee");
		}
	}

	/* BOLT #2:
	 *
	 * The receiver MUST check `sig` is valid for the close
	 * transaction, and MUST fail the connection if it is not. */
	theirsig.stype = SIGHASH_ALL;
	if (!proto_to_signature(c->sig, &theirsig.sig))
		return pkt_err(peer, "Invalid signature format");

	close_tx = peer_create_close_tx(peer, c->close_fee);
	if (!check_tx_sig(peer->dstate->secpctx, close_tx, 0,
			  NULL, 0,
			  peer->anchor.witnessscript,
			  &peer->them.commitkey, &theirsig))
		return pkt_err(peer, "Invalid signature");

	tal_free(peer->closing.their_sig);
	peer->closing.their_sig = tal_dup(peer,
					  struct bitcoin_signature, &theirsig);
	peer->closing.their_fee = c->close_fee;

	if (peer->closing.our_fee == peer->closing.their_fee) {
		log_info(peer->log, "accept_pkt_close_sig: That's an ack");
		*acked = true;
	} else {
		/* Adjust our fee to close on their fee. */
		u64 sum;

		/* Beware overflow! */
		sum = (u64)peer->closing.our_fee + peer->closing.their_fee;

		peer->closing.our_fee = sum / 2;
		if (peer->closing.our_fee & 1)
			peer->closing.our_fee++;

		log_info(peer->log, "accept_pkt_close_sig: we change to %"PRIu64,
			 peer->closing.our_fee);

		/* Corner case: we may now agree with them. */
		if (peer->closing.our_fee == peer->closing.their_fee)
			*we_agree = true;
	}

	/* FIXME: Dynamic fee! */
	return NULL;
}
예제 #18
0
void *
tcp_daemon(void *door)
{
	pthread_t thread;
	pthread_attr_t t_attr;

	PACKET rpkt;
	struct sockaddr_storage addr;
	socklen_t addrlen = sizeof addr;
	inet_prefix ip;

	fd_set fdset;
	int fd, ret, err, i;

	interface *ifs;
	int max_sk_idx, dev_sk[me.cur_ifs_n];

	u_short tcp_port = *(u_short *) door;
	const char *ntop;

	pthread_attr_init(&t_attr);
	pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED);

	debug(DBG_SOFT, "Preparing the tcp listening socket on port %d",
		  tcp_port);

	err = sockets_all_ifs(my_family, SOCK_STREAM, tcp_port, me.cur_ifs,
						  me.cur_ifs_n, dev_sk, &max_sk_idx);
	if (!err)
		return NULL;
	else if (err < 0)
		fatal("Creation of the %s daemon aborted. "
			  "Is there another ntkd running?", "tcp");

	pthread_mutex_init(&tcp_exec_lock, 0);

	for (i = 0; i < me.cur_ifs_n; i++) {
		if (!dev_sk[i])
			continue;
		/* 
		 * While we are accepting the connections we keep the socket non
		 * blocking.
		 */
		if (set_nonblock_sk(dev_sk[i])) {
			pthread_mutex_unlock(&tcp_daemon_lock);
			return NULL;
		}

		/* Shhh, it's listening... */
		if (listen(dev_sk[i], 5) == -1) {
			inet_close(&dev_sk[i]);
			pthread_mutex_unlock(&tcp_daemon_lock);
			return NULL;
		}
	}

	debug(DBG_NORMAL, "Tcp daemon on port %d up & running", tcp_port);
	pthread_mutex_unlock(&tcp_daemon_lock);
	for (;;) {
		FD_ZERO(&fdset);

		if (!me.cur_ifs_n) {
			/* All the devices have been removed while ntkd was
			 * running, sleep well */
			sleep(1);
			continue;
		}

		for (i = 0; i < me.cur_ifs_n; i++)
			if (dev_sk[i])
				FD_SET(dev_sk[i], &fdset);

		ret = select(dev_sk[max_sk_idx] + 1, &fdset, NULL, NULL, NULL);
		if (sigterm_timestamp)
			/* NetsukukuD has been closed */
			break;
		if (ret < 0 && errno != EINTR)
			error("daemon_tcp: select error: %s", strerror(errno));
		if (ret < 0)
			continue;

		for (i = 0; i < me.cur_ifs_n; i++) {
			ifs = &me.cur_ifs[i];
			if (!dev_sk[i])
				continue;

			if (!FD_ISSET(dev_sk[i], &fdset))
				continue;

			fd = accept(dev_sk[i], (struct sockaddr *) &addr, &addrlen);
			if (fd == -1) {
				if (errno != EINTR && errno != EWOULDBLOCK)
					error("daemon_tcp: accept(): %s", strerror(errno));
				continue;
			}

			setzero(&rpkt, sizeof(PACKET));
			pkt_addsk(&rpkt, my_family, fd, SKT_TCP);
			pkt_add_dev(&rpkt, ifs, 0);
			rpkt.flags = MSG_WAITALL;
			pkt_addport(&rpkt, tcp_port);

			ntop = 0;
			sockaddr_to_inet((struct sockaddr *) &addr, &ip, 0);
			pkt_addfrom(&rpkt, &ip);
			if (server_opt.dbg_lvl)
				ntop = inet_to_str(ip);

			if ((ret = add_accept(ip, 0))) {
				debug(DBG_NORMAL, "ACPT: drop connection with %s: "
					  "Accept table full.", ntop);

				/* Omg, we cannot take it anymore, go away: ACK_NEGATIVE */
				pkt_err(rpkt, ret, 1);
				inet_close(&fd);
				continue;
			} else {
				/* 
				 * Ok, the connection is good, send back the
				 * ACK_AFFERMATIVE.
				 */
				pkt_addto(&rpkt, &rpkt.from);
				send_rq(&rpkt, 0, ACK_AFFERMATIVE, 0, 0, 0, 0);
			}

			if (unset_nonblock_sk(fd))
				continue;

			pthread_mutex_lock(&tcp_exec_lock);
			err =
				pthread_create(&thread, &t_attr, tcp_recv_loop,
							   (void *) &rpkt);
			pthread_detach(thread);
			pthread_mutex_lock(&tcp_exec_lock);
			pthread_mutex_unlock(&tcp_exec_lock);
		}
	}
	return NULL;
}
예제 #19
0
Pkt *pkt_err_unexpected(struct peer *peer, const Pkt *pkt)
{
	return pkt_err(peer, "Unexpected packet %s", pkt_name(pkt->pkt_case));
}