diff options
author | Alexander Motin <mav@FreeBSD.org> | 2008-12-06 23:00:48 +0000 |
---|---|---|
committer | Alexander Motin <mav@FreeBSD.org> | 2008-12-06 23:00:48 +0000 |
commit | 11d1cade739439af020f7dfeefef0ef09af2230c (patch) | |
tree | a345b547c6063fb235f59c6bd6f118381261153f /sys/netgraph/ng_mppc.c | |
parent | d493985afd97ef2fab60f8d924bf8d8cf8b29d35 (diff) | |
download | src-11d1cade739439af020f7dfeefef0ef09af2230c.tar.gz src-11d1cade739439af020f7dfeefef0ef09af2230c.zip |
Carefully handle memory errors to keep peers compression/encryption state
consistent. There are some cases reported where peers fatally getting out
of sync without any visible reason. I hope this solve the problem.
Notes
Notes:
svn path=/head/; revision=185723
Diffstat (limited to 'sys/netgraph/ng_mppc.c')
-rw-r--r-- | sys/netgraph/ng_mppc.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/sys/netgraph/ng_mppc.c b/sys/netgraph/ng_mppc.c index 2e9d932d4c04..472968f8d82c 100644 --- a/sys/netgraph/ng_mppc.c +++ b/sys/netgraph/ng_mppc.c @@ -492,17 +492,18 @@ ng_mppc_compress(node_p node, struct mbuf **datap) /* Work with contiguous regions of memory. */ inlen = m->m_pkthdr.len; inbuf = malloc(inlen, M_NETGRAPH_MPPC, M_NOWAIT); - if (inbuf == NULL) { - m_freem(m); - return (ENOMEM); - } + if (inbuf == NULL) + goto err1; m_copydata(m, 0, inlen, (caddr_t)inbuf); outlen = MPPC_MAX_BLOWUP(inlen); outbuf = malloc(outlen, M_NETGRAPH_MPPC, M_NOWAIT); if (outbuf == NULL) { - m_freem(m); free(inbuf, M_NETGRAPH_MPPC); +err1: + m_freem(m); + MPPC_InitCompressionHistory(d->history); + d->flushed = 1; return (ENOMEM); } @@ -538,8 +539,13 @@ ng_mppc_compress(node_p node, struct mbuf **datap) free(outbuf, M_NETGRAPH_MPPC); /* Check m_devget() result. */ - if (m == NULL) + if (m == NULL) { + if (!d->flushed) { + MPPC_InitCompressionHistory(d->history); + d->flushed = 1; + } return (ENOMEM); + } } #endif @@ -551,6 +557,18 @@ ng_mppc_compress(node_p node, struct mbuf **datap) /* Set header bits */ header |= MPPC_FLAG_ENCRYPTED; + /* We must own the mbuf chain exclusively to modify it. */ + m = m_unshare(m, M_DONTWAIT); + if (m == NULL) { + if (!d->flushed) { +#ifdef NETGRAPH_MPPC_COMPRESSION + MPPC_InitCompressionHistory(d->history); +#endif + d->flushed = 1; + } + return (ENOMEM); + } + /* Update key if it's time */ if ((d->cfg.bits & MPPE_STATELESS) != 0 || (d->cc & MPPE_UPDATE_MASK) == MPPE_UPDATE_FLAG) { @@ -562,11 +580,6 @@ ng_mppc_compress(node_p node, struct mbuf **datap) rc4_init(&d->rc4, d->key, KEYLEN(d->cfg.bits)); } - /* We must own the mbuf chain exclusively to modify it. */ - m = m_unshare(m, M_DONTWAIT); - if (m == NULL) - return (ENOMEM); - /* Encrypt packet */ m1 = m; while (m1) { |