Annotation of embedaddon/mpd/src/ccp_deflate.c, revision 1.1
1.1 ! misho 1:
! 2: /*
! 3: * ccp_deflate.c
! 4: *
! 5: * Written by Alexander Motin <mav@FreeBSD.org>
! 6: */
! 7:
! 8: #include "defs.h"
! 9:
! 10: #ifdef CCP_DEFLATE
! 11:
! 12: #include "ppp.h"
! 13: #include "ccp.h"
! 14: #include "util.h"
! 15: #include "ngfunc.h"
! 16:
! 17: #include <netgraph/ng_message.h>
! 18: #include <netgraph.h>
! 19:
! 20: /*
! 21: * INTERNAL FUNCTIONS
! 22: */
! 23:
! 24: static int DeflateInit(Bund b, int direction);
! 25: static int DeflateConfigure(Bund b);
! 26: static char *DeflateDescribe(Bund b, int xmit, char *buf, size_t len);
! 27: static void DeflateCleanup(Bund b, int direction);
! 28:
! 29: static u_char *DeflateBuildConfigReq(Bund b, u_char *cp, int *ok);
! 30: static void DeflateDecodeConfigReq(Fsm fp, FsmOption opt, int mode);
! 31: static Mbuf DeflateRecvResetReq(Bund b, int id, Mbuf bp, int *noAck);
! 32: static Mbuf DeflateSendResetReq(Bund b);
! 33: static void DeflateRecvResetAck(Bund b, int id, Mbuf bp);
! 34: static int DeflateNegotiated(Bund b, int xmit);
! 35: static int DeflateSubtractBloat(Bund b, int size);
! 36: static int DeflateStat(Context ctx, int dir);
! 37:
! 38: /*
! 39: * GLOBAL VARIABLES
! 40: */
! 41:
! 42: const struct comptype gCompDeflateInfo =
! 43: {
! 44: "deflate",
! 45: CCP_TY_DEFLATE,
! 46: 2,
! 47: DeflateInit,
! 48: DeflateConfigure,
! 49: NULL,
! 50: DeflateDescribe,
! 51: DeflateSubtractBloat,
! 52: DeflateCleanup,
! 53: DeflateBuildConfigReq,
! 54: DeflateDecodeConfigReq,
! 55: DeflateSendResetReq,
! 56: DeflateRecvResetReq,
! 57: DeflateRecvResetAck,
! 58: DeflateNegotiated,
! 59: DeflateStat,
! 60: NULL,
! 61: NULL,
! 62: };
! 63:
! 64: /*
! 65: * DeflateInit()
! 66: */
! 67:
! 68: static int
! 69: DeflateInit(Bund b, int dir)
! 70: {
! 71: DeflateInfo const deflate = &b->ccp.deflate;
! 72: struct ng_deflate_config conf;
! 73: struct ngm_mkpeer mp;
! 74: char path[NG_PATHSIZ];
! 75: const char *deflatehook, *ppphook;
! 76: ng_ID_t id;
! 77:
! 78: /* Initialize configuration structure */
! 79: memset(&conf, 0, sizeof(conf));
! 80: conf.enable = 1;
! 81: if (dir == COMP_DIR_XMIT) {
! 82: ppphook = NG_PPP_HOOK_COMPRESS;
! 83: deflatehook = NG_DEFLATE_HOOK_COMP;
! 84: conf.windowBits = deflate->xmit_windowBits;
! 85: } else {
! 86: ppphook = NG_PPP_HOOK_DECOMPRESS;
! 87: deflatehook = NG_DEFLATE_HOOK_DECOMP;
! 88: conf.windowBits = deflate->recv_windowBits;
! 89: }
! 90:
! 91: /* Attach a new DEFLATE node to the PPP node */
! 92: snprintf(path, sizeof(path), "[%x]:", b->nodeID);
! 93: strcpy(mp.type, NG_DEFLATE_NODE_TYPE);
! 94: strcpy(mp.ourhook, ppphook);
! 95: strcpy(mp.peerhook, deflatehook);
! 96: if (NgSendMsg(gCcpCsock, path,
! 97: NGM_GENERIC_COOKIE, NGM_MKPEER, &mp, sizeof(mp)) < 0) {
! 98: Perror("[%s] can't create %s node", b->name, mp.type);
! 99: return(-1);
! 100: }
! 101:
! 102: strlcat(path, ppphook, sizeof(path));
! 103:
! 104: id = NgGetNodeID(-1, path);
! 105: if (dir == COMP_DIR_XMIT) {
! 106: b->ccp.comp_node_id = id;
! 107: } else {
! 108: b->ccp.decomp_node_id = id;
! 109: }
! 110:
! 111: /* Configure DEFLATE node */
! 112: snprintf(path, sizeof(path), "[%x]:", id);
! 113: if (NgSendMsg(gCcpCsock, path,
! 114: NGM_DEFLATE_COOKIE, NGM_DEFLATE_CONFIG, &conf, sizeof(conf)) < 0) {
! 115: Perror("[%s] can't config %s node at %s",
! 116: b->name, NG_DEFLATE_NODE_TYPE, path);
! 117: NgFuncShutdownNode(gCcpCsock, b->name, path);
! 118: return(-1);
! 119: }
! 120:
! 121: return 0;
! 122: }
! 123:
! 124: /*
! 125: * DeflateConfigure()
! 126: */
! 127:
! 128: static int
! 129: DeflateConfigure(Bund b)
! 130: {
! 131: CcpState const ccp = &b->ccp;
! 132: DeflateInfo const deflate = &ccp->deflate;
! 133:
! 134: deflate->xmit_windowBits=15;
! 135: deflate->recv_windowBits=0;
! 136:
! 137: return(0);
! 138: }
! 139:
! 140: /*
! 141: * DeflateCleanup()
! 142: */
! 143:
! 144: static char *
! 145: DeflateDescribe(Bund b, int dir, char *buf, size_t len)
! 146: {
! 147: CcpState const ccp = &b->ccp;
! 148: DeflateInfo const deflate = &ccp->deflate;
! 149:
! 150: switch (dir) {
! 151: case COMP_DIR_XMIT:
! 152: snprintf(buf, len, "win %d", deflate->xmit_windowBits);
! 153: break;
! 154: case COMP_DIR_RECV:
! 155: snprintf(buf, len, "win %d", deflate->recv_windowBits);
! 156: break;
! 157: default:
! 158: assert(0);
! 159: return(NULL);
! 160: }
! 161: return (buf);
! 162: }
! 163:
! 164: /*
! 165: * DeflateCleanup()
! 166: */
! 167:
! 168: void
! 169: DeflateCleanup(Bund b, int dir)
! 170: {
! 171: char path[NG_PATHSIZ];
! 172:
! 173: /* Remove node */
! 174: if (dir == COMP_DIR_XMIT) {
! 175: snprintf(path, sizeof(path), "[%x]:", b->ccp.comp_node_id);
! 176: b->ccp.comp_node_id = 0;
! 177: } else {
! 178: snprintf(path, sizeof(path), "[%x]:", b->ccp.decomp_node_id);
! 179: b->ccp.decomp_node_id = 0;
! 180: }
! 181: NgFuncShutdownNode(gCcpCsock, b->name, path);
! 182: }
! 183:
! 184: /*
! 185: * DeflateRecvResetReq()
! 186: */
! 187:
! 188: static Mbuf
! 189: DeflateRecvResetReq(Bund b, int id, Mbuf bp, int *noAck)
! 190: {
! 191: char path[NG_PATHSIZ];
! 192: /* Forward ResetReq to the DEFLATE compression node */
! 193: snprintf(path, sizeof(path), "[%x]:", b->ccp.comp_node_id);
! 194: if (NgSendMsg(gCcpCsock, path,
! 195: NGM_DEFLATE_COOKIE, NGM_DEFLATE_RESETREQ, NULL, 0) < 0) {
! 196: Perror("[%s] reset-req to %s node", b->name, NG_DEFLATE_NODE_TYPE);
! 197: }
! 198: return(NULL);
! 199: }
! 200:
! 201: /*
! 202: * DeflateSendResetReq()
! 203: */
! 204:
! 205: static Mbuf
! 206: DeflateSendResetReq(Bund b)
! 207: {
! 208: return(NULL);
! 209: }
! 210:
! 211: /*
! 212: * DeflateRecvResetAck()
! 213: */
! 214:
! 215: static void
! 216: DeflateRecvResetAck(Bund b, int id, Mbuf bp)
! 217: {
! 218: char path[NG_PATHSIZ];
! 219: /* Forward ResetReq to the DEFLATE compression node */
! 220: snprintf(path, sizeof(path), "[%x]:", b->ccp.decomp_node_id);
! 221: if (NgSendMsg(gCcpCsock, path,
! 222: NGM_DEFLATE_COOKIE, NGM_DEFLATE_RESETREQ, NULL, 0) < 0) {
! 223: Perror("[%s] reset-ack to %s node", b->name, NG_DEFLATE_NODE_TYPE);
! 224: }
! 225: }
! 226:
! 227: /*
! 228: * DeflateBuildConfigReq()
! 229: */
! 230:
! 231: static u_char *
! 232: DeflateBuildConfigReq(Bund b, u_char *cp, int *ok)
! 233: {
! 234: CcpState const ccp = &b->ccp;
! 235: DeflateInfo const deflate = &ccp->deflate;
! 236: u_int16_t opt;
! 237:
! 238: if (deflate->xmit_windowBits > 0) {
! 239: opt = ((deflate->xmit_windowBits-8)<<12) + (8<<8) + (0<<2) + 0;
! 240:
! 241: cp = FsmConfValue(cp, CCP_TY_DEFLATE, -2, &opt);
! 242: *ok = 1;
! 243: }
! 244: return (cp);
! 245: }
! 246:
! 247: /*
! 248: * DeflateDecodeConfigReq()
! 249: */
! 250:
! 251: static void
! 252: DeflateDecodeConfigReq(Fsm fp, FsmOption opt, int mode)
! 253: {
! 254: Bund b = (Bund)fp->arg;
! 255: CcpState const ccp = &b->ccp;
! 256: DeflateInfo const deflate = &ccp->deflate;
! 257: u_int16_t o;
! 258: u_char window, method, chk;
! 259:
! 260: /* Sanity check */
! 261: if (opt->len != 4) {
! 262: Log(LG_CCP, ("[%s] bogus length %d", b->name, opt->len));
! 263: if (mode == MODE_REQ)
! 264: FsmRej(fp, opt);
! 265: return;
! 266: }
! 267:
! 268: /* Get bits */
! 269: memcpy(&o, opt->data, 2);
! 270: o = ntohs(o);
! 271: window = (o>>12)&0x000F;
! 272: method = (o>>8)&0x000F;
! 273: chk = o&0x0003;
! 274:
! 275: /* Display it */
! 276: Log(LG_CCP, ("[%s] 0x%04x: w:%d, m:%d, c:%d", b->name, o, window, method, chk));
! 277:
! 278: /* Deal with it */
! 279: switch (mode) {
! 280: case MODE_REQ:
! 281: if ((window > 0) && (window<=7) && (method == 8) && (chk == 0)) {
! 282: deflate->recv_windowBits = window + 8;
! 283: FsmAck(fp, opt);
! 284: } else {
! 285: o = htons((7<<12) + (8<<8) + (0<<2) + 0);
! 286: memcpy(opt->data, &o, 2);
! 287: FsmNak(fp, opt);
! 288: }
! 289: break;
! 290:
! 291: case MODE_NAK:
! 292: if ((window > 0) && (window<=7) && (method == 8) && (chk == 0))
! 293: deflate->xmit_windowBits = window + 8;
! 294: else {
! 295: deflate->xmit_windowBits = 0;
! 296: }
! 297: break;
! 298: }
! 299: }
! 300:
! 301: /*
! 302: * DeflateNegotiated()
! 303: */
! 304:
! 305: static int
! 306: DeflateNegotiated(Bund b, int dir)
! 307: {
! 308: return 1;
! 309: }
! 310:
! 311: /*
! 312: * DeflateSubtractBloat()
! 313: */
! 314:
! 315: static int
! 316: DeflateSubtractBloat(Bund b, int size)
! 317: {
! 318: return(size + CCP_OVERHEAD); /* Compression compensate header size */
! 319: }
! 320:
! 321: static int
! 322: DeflateStat(Context ctx, int dir)
! 323: {
! 324: Bund b = ctx->bund;
! 325: char path[NG_PATHSIZ];
! 326: struct ng_deflate_stats stats;
! 327: union {
! 328: u_char buf[sizeof(struct ng_mesg) + sizeof(stats)];
! 329: struct ng_mesg reply;
! 330: } u;
! 331:
! 332: switch (dir) {
! 333: case COMP_DIR_XMIT:
! 334: snprintf(path, sizeof(path), "mpd%d-%s:%s", gPid, b->name,
! 335: NG_PPP_HOOK_COMPRESS);
! 336: break;
! 337: case COMP_DIR_RECV:
! 338: snprintf(path, sizeof(path), "mpd%d-%s:%s", gPid, b->name,
! 339: NG_PPP_HOOK_DECOMPRESS);
! 340: break;
! 341: default:
! 342: assert(0);
! 343: }
! 344: if (NgFuncSendQuery(path, NGM_DEFLATE_COOKIE, NGM_DEFLATE_GET_STATS, NULL, 0,
! 345: &u.reply, sizeof(u), NULL) < 0) {
! 346: Perror("[%s] can't get %s stats", b->name, NG_DEFLATE_NODE_TYPE);
! 347: return(0);
! 348: }
! 349: memcpy(&stats, u.reply.data, sizeof(stats));
! 350: switch (dir) {
! 351: case COMP_DIR_XMIT:
! 352: Printf("\tBytes\t: %llu -> %llu (%+lld%%)\r\n",
! 353: stats.InOctets,
! 354: stats.OutOctets,
! 355: ((stats.InOctets!=0)?
! 356: ((int64_t)(stats.OutOctets - stats.InOctets)*100/(int64_t)stats.InOctets):
! 357: 0));
! 358: Printf("\tFrames\t: %llu -> %lluc + %lluu\r\n",
! 359: stats.FramesPlain,
! 360: stats.FramesComp,
! 361: stats.FramesUncomp);
! 362: Printf("\tErrors\t: %llu\r\n",
! 363: stats.Errors);
! 364: break;
! 365: case COMP_DIR_RECV:
! 366: Printf("\tBytes\t: %llu <- %llu (%+lld%%)\r\n",
! 367: stats.OutOctets,
! 368: stats.InOctets,
! 369: ((stats.OutOctets!=0)?
! 370: ((int64_t)(stats.InOctets - stats.OutOctets)*100/(int64_t)stats.OutOctets):
! 371: 0));
! 372: Printf("\tFrames\t: %llu <- %lluc + %lluu\r\n",
! 373: stats.FramesPlain,
! 374: stats.FramesComp,
! 375: stats.FramesUncomp);
! 376: Printf("\tErrors\t: %llu\r\n",
! 377: stats.Errors);
! 378: break;
! 379: default:
! 380: assert(0);
! 381: }
! 382: return (0);
! 383: }
! 384:
! 385: #endif /* CCP_DEFLATE */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>