* purged, too. This makes it much harder to sneak in some
* unauthenticated data in the clock filter.
*/
+ DPRINTF(1, ("peer_crypto_clear: at %ld next %ld assoc ID %d\n",
+ current_time, peer->nextdate, peer->associd));
+
#ifdef OPENSSL
- key_expire(peer);
+ peer->assoc = 0;
+ peer->crypto = 0;
+
if (peer->pkey != NULL)
EVP_PKEY_free(peer->pkey);
- if (peer->ident_pkey != NULL)
- EVP_PKEY_free(peer->ident_pkey);
+ peer->pkey = NULL;
+
+ memset(&peer->first, 0, sizeof(peer->first));
+ memset(&peer->last, 0, sizeof(peer->last));
+
+ peer->digest = NULL; /* XXX MEMLEAK? check whether this needs to be freed in any way - never was freed */
+
if (peer->subject != NULL)
free(peer->subject);
+ peer->subject = NULL;
+
if (peer->issuer != NULL)
free(peer->issuer);
+ peer->issuer = NULL;
+
+ peer->pkeyid = 0;
+
+ peer->pcookie = 0;
+
+ if (peer->ident_pkey != NULL)
+ EVP_PKEY_free(peer->ident_pkey);
+ peer->ident_pkey = NULL;
+
+ memset(&peer->fstamp, 0, sizeof(peer->fstamp));
+
if (peer->iffval != NULL)
BN_free(peer->iffval);
+ peer->iffval = NULL;
+
if (peer->grpkey != NULL)
BN_free(peer->grpkey);
- value_free(&peer->tai_leap);
+ peer->grpkey = NULL;
+
+ value_free(&peer->cookval);
+ value_free(&peer->recval);
+
if (peer->cmmd != NULL) {
free(peer->cmmd);
peer->cmmd = NULL;
keyid_t xkeyid = 0; /* transmit key ID */
l_fp xmt_tx;
- /*
- * If the crypto is broken, don't make it worse. Otherwise,
- * initialize the header fields.
- */
+ if (!peer->dstadr) /* don't bother with peers without interface */
+ return;
+
- xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, peer->version,
- peer->hmode);
- xpkt.stratum = STRATUM_TO_PKT(sys_stratum);
- xpkt.ppoll = peer->hpoll;
- xpkt.precision = sys_precision;
- if (sys_stratum < sys_orphan)
+ /*
+ * This is deliciously complicated. There are three cases.
+ *
+ * case leap stratum refid delay dispersion
+ *
+ * normal system system system system system
+ * orphan child 00 orphan system orphan system
+ * orphan parent 00 orphan loopbk 0 0
+ */
+ /*
+ * This is a normal packet. Use the system variables.
+ */
+ if (sys_stratum < sys_orphan) {
+ xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap,
+ peer->version, peer->hmode);
+ xpkt.stratum = STRATUM_TO_PKT(sys_stratum);
+ xpkt.refid = sys_refid;
xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay));
- else if (sys_peer != NULL)
+ xpkt.rootdispersion =
+ HTONS_FP(DTOUFP(sys_rootdispersion));
+
+ /*
+ * This is a orphan child packet. The host is synchronized to an
+ * orphan parent. Show leap synchronized, orphan stratum, system
+ * reference ID, orphan root delay and system root dispersion.
+ */
+ } else if (sys_peer != NULL) {
+ xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
+ peer->version, peer->hmode);
+ xpkt.stratum = STRATUM_TO_PKT(sys_orphan);
+ xpkt.refid = htonl(LOOPBACKADR);
xpkt.rootdelay = HTONS_FP(DTOFP(sys_orphandelay));
- else
+ xpkt.rootdispersion =
+ HTONS_FP(DTOUFP(sys_rootdispersion));
+
+ /*
+ * This is an orphan parent. Show leap synchronized, orphan
+ * stratum, loopack reference ID and zero root delay and root
+ * dispersion.
+ */
+ } else {
+ xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
+ peer->version, peer->hmode);
+ xpkt.stratum = STRATUM_TO_PKT(sys_orphan);
+ xpkt.refid = sys_refid;
xpkt.rootdelay = 0;
- xpkt.rootdispersion = HTONS_FP(DTOUFP(sys_rootdispersion));
- xpkt.refid = sys_refid;
+ xpkt.rootdispersion = 0;
+ }
+ xpkt.ppoll = peer->hpoll;
+ xpkt.precision = sys_precision;
HTONL_FP(&sys_reftime, &xpkt.reftime);
HTONL_FP(&peer->org, &xpkt.org);
HTONL_FP(&peer->rec, &xpkt.rec);
peer->cmmd = NULL;
}
if (exten != NULL) {
- if (exten->opcode != 0)
- sendlen += crypto_xmit(&xpkt,
+ int ltemp = 0;
+
+ if (exten->opcode != 0) {
+ ltemp = crypto_xmit(&xpkt,
- &peer->srcadr, sendlen, exten, 0);
+ &peer->srcadr, sendlen, exten, 0);
- if (ntohl(exten->opcode) & CRYPTO_ERROR) {
- peer->flash |= TEST9; /* crypto error */
- free(exten);
- return;
+ if (ltemp == 0) {
+ peer->flash |= TEST9; /* crypto error */
+ free(exten);
+ return;
+ }
}
+ sendlen += ltemp;
free(exten);
}
ULOGTOD(sys_poll))
rval |= TEST11; /* distance exceeded */
- if (peer->stratum > 1 && (!peer->dstadr || peer->refid ==
- peer->dstadr->addr_refid || (peer->refid == sys_refid &&
- peer->refid != htonl(LOOPBACKADR))))
+ /*
+ * A loop error occurs if the remote peer is synchronized to the
+ * local peer of if the remote peer is synchronized to the same
+ * server as the local peer, but only if the remote peer is not
+ * the orphan parent.
+ */
+ if (peer->stratum > 1 && peer->refid != htonl(LOOPBACKADR) &&
- (peer->refid == peer->dstadr->addr_refid || peer->refid ==
++ ((!peer->dstadr || peer->refid == peer->dstadr->addr_refid) || peer->refid ==
+ sys_refid))
rval |= TEST12; /* synch loop */
+ /*
+ * An unreachable error occurs if the server is unreachable or
+ * the noselect bit is set.
+ */
if (!peer->reach || peer->flags & FLAG_NOSELECT)
rval |= TEST13; /* unreachable */