38#include <sys/kernel.h>
40#include <sys/malloc.h>
41#include <sys/endian.h>
43#include <sys/syslog.h>
44#include <contrib/zlib/zlib.h>
51#include "opt_netgraph.h"
54 "netgraph deflate node");
57#define DEFLATE_HDRLEN 2
59#define PROT_COMPD 0x00fd
61#define DEFLATE_BUF_SIZE 4096
162#define ERROUT(x) do { error = (x); goto done; } while (0)
177 priv = malloc(
sizeof(*
priv), M_NETGRAPH_DEFLATE, M_WAITOK | M_ZERO);
241 if (
priv->cfg.enable) {
243 deflateEnd(&
priv->cx);
245 inflateEnd(&
priv->cx);
246 priv->cfg.enable = 0;
252 if (
priv->cfg.enable) {
253 priv->cx.next_in = NULL;
255 if (
priv->compress) {
256 if ((res = deflateInit2(&
priv->cx,
257 Z_DEFAULT_COMPRESSION, Z_DEFLATED,
259 Z_DEFAULT_STRATEGY)) != Z_OK) {
261 "deflateInit2: error %d, %s\n",
263 priv->cfg.enable = 0;
267 if ((res = inflateInit2(&
priv->cx,
270 "inflateInit2: error %d, %s\n",
272 priv->cfg.enable = 0;
327 struct mbuf *m, *out;
330 if (!
priv->cfg.enable) {
337 if (
priv->compress) {
340 log(LOG_NOTICE,
"%s: error: %d\n", __func__, error);
346 log(LOG_NOTICE,
"%s: error: %d\n", __func__, error);
347 if (
priv->ctrlnode != 0) {
375 if (
priv->cfg.enable) {
377 deflateEnd(&
priv->cx);
379 inflateEnd(&
priv->cx);
382 free(
priv, M_NETGRAPH_DEFLATE);
397 if (
priv->cfg.enable) {
399 deflateEnd(&
priv->cx);
401 inflateEnd(&
priv->cx);
402 priv->cfg.enable = 0;
429 inlen = m->m_pkthdr.len;
441 m = m_unshare(m, M_NOWAIT);
448 m_copydata(m, 0, inlen, (caddr_t)
priv->inbuf);
453 if (
priv->inbuf[0] != 0) {
455 priv->cx.avail_in = inlen;
458 priv->cx.avail_in = inlen - 1;
464 rtn = deflate(&
priv->cx, Z_SYNC_FLUSH);
469 log(LOG_NOTICE,
"ng_deflate: compression error: %d (%s)\n",
476 outlen -=
priv->cx.avail_out;
486 MPASS(
priv->outbuf[outlen + 0] == 0x00);
487 MPASS(
priv->outbuf[outlen + 1] == 0x00);
488 MPASS(
priv->outbuf[outlen + 2] == 0xff);
489 MPASS(
priv->outbuf[outlen + 3] == 0xff);
492 if (outlen > inlen) {
500 be16enc(
priv->outbuf + 2,
priv->seqnum);
503 m_copyback(m, 0, outlen, (caddr_t)
priv->outbuf);
504 if (m->m_pkthdr.len < outlen) {
508 }
else if (outlen < m->m_pkthdr.len)
509 m_adj(m, outlen - m->m_pkthdr.len);
529 int outlen, inlen, datalen;
535 static u_char EMPTY_BLOCK[4] = { 0x00, 0x00, 0xff, 0xff };
540 inlen = m->m_pkthdr.len;
550 m = m_unshare(m, M_NOWAIT);
557 m_copydata(m, 0, inlen, (caddr_t)
priv->inbuf);
560 if ((
priv->inbuf[0] & 0x01) != 0) {
561 proto =
priv->inbuf[0];
564 proto = be16dec(
priv->inbuf);
575 rseqnum = be16dec(
priv->inbuf + offset);
577 if (rseqnum !=
priv->seqnum) {
579 log(LOG_NOTICE,
"ng_deflate: wrong sequence: %u "
580 "instead of %u\n", rseqnum,
priv->seqnum);
590 priv->cx.next_in =
priv->inbuf + offset;
591 priv->cx.avail_in = inlen - offset;
593 priv->cx.next_out =
priv->outbuf + 1;
594 priv->cx.avail_out = outlen - 1;
597 rtn = inflate(&
priv->cx, Z_SYNC_FLUSH);
600 if (rtn != Z_OK && rtn != Z_STREAM_END) {
604 log(LOG_NOTICE,
"%s: decompression error: %d (%s)\n",
605 __func__, rtn,
priv->cx.msg);
618 if (inflateSyncPoint(&
priv->cx)) {
619 priv->cx.avail_in = 4;
620 priv->cx.next_in = EMPTY_BLOCK;
621 inflate(&
priv->cx, Z_SYNC_FLUSH);
625 outlen -=
priv->cx.avail_out;
628 if ((
priv->outbuf[1] & 0x01) != 0) {
631 m_copyback(m, 0, outlen, (caddr_t)
priv->outbuf);
635 m_copyback(m, 0, outlen, (caddr_t)(
priv->outbuf + 1));
637 if (m->m_pkthdr.len < outlen) {
642 }
else if (outlen < m->m_pkthdr.len)
643 m_adj(m, outlen - m->m_pkthdr.len);
655 datalen = inlen - offset + 1;
657 headbuf[1] = datalen & 0xff;
658 headbuf[2] = datalen >> 8;
659 headbuf[3] = (~datalen) & 0xff;
660 headbuf[4] = (~datalen) >> 8;
662 priv->cx.next_in = headbuf;
663 priv->cx.avail_in =
sizeof(headbuf);
667 rtn = inflate(&
priv->cx, Z_NO_FLUSH);
669 if (
priv->inbuf[0] == 0) {
672 priv->cx.avail_in = inlen - 1;
675 priv->cx.avail_in = inlen;
680 rtn = inflate(&
priv->cx, Z_SYNC_FLUSH);
685 log(LOG_NOTICE,
"%s: inflate error: %d (%s)\n",
686 __func__, rtn,
priv->cx.msg);
712 if (
priv->cfg.enable) {
714 deflateReset(&
priv->cx);
716 inflateReset(&
priv->cx);
#define NG_HOOK_NODE(hook)
int ng_rcvmsg_t(node_p node, item_p item, hook_p lasthook)
int ng_disconnect_t(hook_p hook)
#define NG_NODE_SET_PRIVATE(node, val)
#define NG_RESPOND_MSG(error, here, item, resp)
#define NG_NODE_IS_VALID(node)
#define NG_NODE_FORCE_WRITER(node)
#define NG_NODE_UNREF(node)
int ng_rmnode_self(node_p here)
#define NG_FWD_NEW_DATA(error, item, hook, m)
#define NG_SEND_MSG_ID(error, here, msg, ID, retaddr)
int ng_rcvdata_t(hook_p hook, item_p item)
int ng_shutdown_t(node_p node)
#define NG_FREE_ITEM(item)
int ng_constructor_t(node_p node)
#define NG_NODE_NUMHOOKS(node)
#define NGI_GET_MSG(i, m)
#define NG_NODE_PRIVATE(node)
int ng_newhook_t(node_p node, hook_p hook, const char *name)
static ng_rcvdata_t ng_deflate_rcvdata
static const struct ng_parse_type ng_deflate_config_type
static ng_disconnect_t ng_deflate_disconnect
static ng_shutdown_t ng_deflate_shutdown
static const struct ng_cmdlist ng_deflate_cmds[]
static const struct ng_parse_type ng_deflate_stat_type
static const struct ng_parse_struct_field ng_deflate_config_type_fields[]
static struct ng_type ng_deflate_typestruct
static MALLOC_DEFINE(M_NETGRAPH_DEFLATE, "netgraph_deflate", "netgraph deflate node")
MODULE_DEPEND(ng_deflate, zlib, 1, 1, 1)
static int ng_deflate_compress(node_p, struct mbuf *, struct mbuf **)
static ng_constructor_t ng_deflate_constructor
NETGRAPH_INIT(deflate, &ng_deflate_typestruct)
static const struct ng_parse_struct_field ng_deflate_stats_type_fields[]
struct ng_deflate_private * priv_p
static ng_newhook_t ng_deflate_newhook
static int ng_deflate_decompress(node_p, struct mbuf *, struct mbuf **)
static ng_rcvmsg_t ng_deflate_rcvmsg
static void ng_deflate_reset_req(node_p)
#define NG_DEFLATE_NODE_TYPE
#define NG_DEFLATE_HOOK_DECOMP
#define NG_DEFLATE_STATS_INFO
@ NGM_DEFLATE_GETCLR_STATS
#define NG_DEFLATE_CONFIG_INFO
#define NGM_DEFLATE_COOKIE
#define NG_DEFLATE_HOOK_COMP
#define NG_MKRESPONSE(rsp, msg, len, how)
#define NG_MKMESSAGE(msg, cookie, cmdid, len, how)
const struct ng_parse_type ng_parse_struct_type
u_char inbuf[DEFLATE_BUF_SIZE]
struct ng_deflate_config cfg
u_char outbuf[DEFLATE_BUF_SIZE]
struct ng_mesg::ng_msghdr header