/* 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; }
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; }
/* 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; }
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; }
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; }
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); }
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; }
/* 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; }
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; }
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; }
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); }
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; }
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; }
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; }
/* * 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; }
/* * 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; }
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; }
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; }
Pkt *pkt_err_unexpected(struct peer *peer, const Pkt *pkt) { return pkt_err(peer, "Unexpected packet %s", pkt_name(pkt->pkt_case)); }