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>