⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 control.c

📁 第二层隧道模块l2tp源码,开发环境为linux
💻 C
📖 第 1 页 / 共 4 页
字号:
            new_hdr->length = buf->len + ehlen;        };        r++;        new_hdr->tid = *r;        r++;        new_hdr->cid = *r;        if (PFBIT (new_hdr->ver))        {            r++;            new_hdr->Ns = *r;            r++;            new_hdr->Nr = *r;        }        else        {            new_hdr->Nr = c->data_seq_num;            new_hdr->Ns = c->data_rec_seq_num;        };        if (PSBIT (new_hdr->ver))        {            r++;            new_hdr->o_size = *r;            r++;            new_hdr->o_pad = *r;        }        else        {            new_hdr->o_size = 0;            new_hdr->o_pad = 0;        }    }    else        new_hdr = h;    /*       * Handle sequence numbers       *     *//*  JLM	if (PRBIT(new_hdr->ver)) {		if (c->pSr > new_hdr->Ns) {			log(LOG_DEBUG, "%s: R-bit set with Ns < pSr!\n",__FUNCTION__);			return -EINVAL;		}#ifdef DEBUG_FLOW		log(LOG_DEBUG, "%s: R-bit set on packet %d\n",__FUNCTION__,new_hdr->Ns);#endif		c->pSr=new_hdr->Ns;	} */#ifdef DEBUG_PAYLOAD    log (LOG_DEBUG, "%s: payload, cid = %d, Ns = %d, Nr = %d\n", __FUNCTION__,         c->cid, new_hdr->Ns, new_hdr->Nr);#endif    if (new_hdr->Ns != c->data_seq_num)    {        /* RFC1982-esque comparison of serial numbers */        if (((new_hdr->Ns < c->data_rec_seq_num) &&             ((c->data_rec_seq_num - new_hdr->Ns) < 32768)) ||            ((new_hdr->Ns > c->data_rec_seq_num) &&             ((c->data_rec_seq_num - new_hdr->Ns) > 32768)))        {#ifdef DEBUG_FLOW            if (DEBUG)                log (LOG_DEBUG,                     "%s: Already seen this packet before (%d < %d)\n",                     __FUNCTION__, new_hdr->Ns, c->pSr);#endif            return -EINVAL;        }        else if (new_hdr->Ns <= c->data_rec_seq_num + PAYLOAD_FUDGE)        {            /* FIXME: I should buffer for out of order packets */#ifdef DEBUG_FLOW            if (DEBUG)                log (LOG_DEBUG,                     "%s: Oops, lost a packet or two (%d != %d).  continuing...\n",                     __FUNCTION__, new_hdr->Ns, c->pSr);#endif            c->data_rec_seq_num = new_hdr->Ns;        }        else        {#ifdef DEBUG_FLOW            if (DEBUG)                log (LOG_DEBUG,                     "%s: Received out of order payload packet (%d != %d)\n",                     __FUNCTION__, new_hdr->Ns, c->pSr);#endif            return -EINVAL;        }    }    else    {        c->data_rec_seq_num++;        c->pnu = -1;    }    /*     * Check to see what the last thing     * we got back was     */    c->pLr = new_hdr->Nr;    buf->start = new_hdr;    buf->len += ehlen;    return 0;}void send_zlb (void *data){    /*     * Send a ZLB.  This procedure should be schedule()able     */    struct call *c;    struct tunnel *t;    struct buffer *buf;    c = (struct call *) data;    if (!c)    {        log (LOG_WARN, "%s: called on NULL call\n", __FUNCTION__);        return;    }    t = c->container;    if (!t)    {        log (LOG_WARN, "%s: called on call with NULL container\n",             __FUNCTION__);        return;    }    /* Update the counter so we know what Lr was when we last transmited a ZLB */    c->prx = c->data_rec_seq_num;    buf = new_payload (t->peer);    add_payload_hdr (t, c, buf);    c->data_seq_num--;                   /* We don't increment on ZLB's */    c->zlb_xmit = NULL;#ifdef DEBUG_ZLB    log (LOG_DEBUG, "%s: sending payload ZLB\n", __FUNCTION__);#endif    udp_xmit (buf);    toss (buf);}inline int write_packet (struct buffer *buf, struct tunnel *t, struct call *c,                         int convert){    /*     * Write a packet, doing sync->async conversion if     * necessary     */    int x;    unsigned char e;    int err;    static unsigned char wbuf[MAX_RECV_SIZE];    int pos = 0;    if (c->fd < 0)    {        if (DEBUG)            log (LOG_DEBUG, "%s: tty is not open yet.\n", __FUNCTION__);        return -EIO;    }    /*     * Skip over header      */    buf->start += sizeof (struct payload_hdr);    buf->len -= sizeof (struct payload_hdr);    c->rx_pkts++;    c->rx_bytes += buf->len;    /*     * FIXME:  What about offset?     */    while (!convert)    {        /* We are given async frames, so write them           directly to the tty */        err = write (c->fd, buf->start, buf->len);        if (err == buf->len)        {            return 0;        }        else if (err == 0)        {            log (LOG_WARN, "%s: wrote no bytes of async packet\n",                 __FUNCTION__);            return -EINVAL;        }        else if (err < 0)        {            if ((errno == EAGAIN) || (errno == EINTR))            {                continue;            }            else            {                log (LOG_WARN, "%s: async write failed: %s\n", __FUNCTION__,                     strerror (errno));            }        }        else if (err < buf->len)        {            log (LOG_WARN, "%s: short write (%d of %d bytes)\n", __FUNCTION__,                 err, buf->len);            return -EINVAL;        }        else if (err > buf->len)        {            log (LOG_WARN, "%s: write returned LONGER than buffer length?\n",                 __FUNCTION__);            return -EINVAL;        }    }    /*     * sync->async conversion if we're doing sync frames     * since the pppd driver will expect async frames     * Write leading flag character     */    add_fcs (buf);    e = PPP_FLAG;    wbuf[pos++] = e;    for (x = 0; x < buf->len; x++)    {        e = *((char *) buf->start + x);        if ((e < 0x20) || (e == PPP_ESCAPE) || (e == PPP_FLAG))        {            /* Escape this */            e = e ^ 0x20;            wbuf[pos++] = PPP_ESCAPE;        }        wbuf[pos++] = e;    }    wbuf[pos++] = PPP_FLAG;    x = write (c->fd, wbuf, pos);    if (x < pos)    {        if (!(errno == EINTR) && !(errno == EAGAIN))        {            /*               * I guess pppd died.  we'll pretend               * everything ended normally             */            if (DEBUG)                log (LOG_WARN, "%s: %s(%d)\n", __FUNCTION__, strerror (errno),                     errno);            c->needclose = -1;            c->fd = -1;            return -EIO;        }    }    return 0;}void handle_special (struct buffer *buf, struct call *c, _u16 call){    /*       * This procedure is called when we have received a packet       * on a call which doesn't exist in our tunnel.  We want to       * send back a ZLB to keep the tunnel alive, on that particular       * call if it was a CDN, otherwise, send a CDN to notify them       * that this call has been terminated.     */    struct buffer *outgoing;    struct tunnel *t = c->container;    /* Don't do anything unless it's a control packet */    if (!CTBIT (*((_u16 *) buf->start)))        return;    /* Temporarily, we make the tunnel have cid of call instead of 0,       but we need to stop any scheduled events (like Hello's in       particular) which might use this value */    c->cid = call;    if (!check_control (buf, t, c))    {        if (buf->len == sizeof (struct control_hdr))        {            /* If it's a ZLB, we ignore it */            if (debug_tunnel)                log (LOG_DEBUG, "%s: ZLB for closed call\n", __FUNCTION__);            c->cid = 0;            return;        }        /* Make a packet with the specified call number */        outgoing = new_outgoing (t);        /* FIXME: If I'm not a CDN, I need to send a CDN */        control_zlb (buf, t, c);        c->cid = 0;        udp_xmit (buf);        toss (buf);    }    else    {        c->cid = 0;        if (debug_tunnel)            log (LOG_DEBUG, "%s: invalid control packet\n", __FUNCTION__);    }}inline int handle_packet (struct buffer *buf, struct tunnel *t,                          struct call *c){    int res;    struct timeval tv;    if (CTBIT (*((_u16 *) buf->start)))    {        /* We have a control packet */        if (!check_control (buf, t, c))        {            c->msgtype = -1;            if (buf->len == sizeof (struct control_hdr))            {#ifdef DEBUG_ZLB                log (LOG_DEBUG, "%s: control ZLB received\n", __FUNCTION__);#endif                t->control_rec_seq_num--;                c->cnu = 0;                if (c->needclose && c->closing)                {                    if (c->container->cLr >= c->closeSs)                    {#ifdef DEBUG_ZLB                        log (LOG_DEBUG, "%s: ZLB for closing message found\n",                             __FUNCTION__);#endif                        c->needclose = 0;                        /* Trigger final closing of call */                    }                }                return 0;            }            else if (!handle_avps (buf, t, c))            {                return control_finish (t, c);            }            else            {                if (debug_tunnel)                    log (LOG_DEBUG, "%s: bad AVP handling!\n", __FUNCTION__);                return -EINVAL;            }        }        else        {            log (LOG_DEBUG, "%s: bad control packet!\n", __FUNCTION__);            return -EINVAL;        }    }    else    {        if (!check_payload (buf, t, c))        {            if (!expand_payload (buf, t, c))            {                if (buf->len > sizeof (struct payload_hdr))                {/*					if (c->throttle) {						if (c->pSs > c->pLr + c->rws) {#ifdef DEBUG_FLOW							log(LOG_DEBUG, "%s: not yet dethrottling call\n",__FUNCTION__);#endif						} else {#ifdef DEBUG_FLOW							log(LOG_DEBUG, "%s: dethrottling call\n",__FUNCTION__);#endif							if (c->dethrottle) deschedule(c->dethrottle);							c->dethrottle=NULL;							c->throttle = 0;						}					} *//*	JLM				res = write_packet(buf,t,c, c->frame & SYNC_FRAMING); */                    res = write_packet (buf, t, c, SYNC_FRAMING);                    if (res)                        return res;                    /*                        * Assuming we wrote to the ppp driver okay, we should                       * do something about ZLB's unless *we* requested no                       * window size or if they we have turned off our fbit.                      *//*					if (c->ourfbit && (c->ourrws > 0)) {						if (c->pSr >= c->prx + c->ourrws - 2) {						We've received enough to fill our receive window.  At						this point, we should immediately send a ZLB!#ifdef DEBUG_ZLB							log(LOG_DEBUG, "%s: Sending immediate ZLB!\n",__FUNCTION__);#endif							if (c->zlb_xmit) {							Deschedule any existing zlb_xmit's								deschedule(c->zlb_xmit);								c->zlb_xmit = NULL;							}							send_zlb((void *)c);						} else {						We need to schedule sending a ZLB.  FIXME:  Should						be 1/4 RTT instead, when rate adaptive stuff is						in place. Spec allows .5 seconds though							tv.tv_sec = 0;							tv.tv_usec = 500000;							if (c->zlb_xmit)								deschedule(c->zlb_xmit);#ifdef DEBUG_ZLB							log(LOG_DEBUG, "%s: scheduling ZLB\n",__FUNCTION__);#endif							c->zlb_xmit = schedule(tv, &send_zlb, (void *)c);						}					} */                    return 0;                }                else if (buf->len == sizeof (struct payload_hdr))                {#ifdef DEBUG_ZLB                    log (LOG_DEBUG, "%s: payload ZLB received\n",                         __FUNCTION__);#endif/*					if (c->throttle) {						if (c->pSs > c->pLr + c->rws) {#ifdef DEBUG_FLOW							log(LOG_DEBUG, "%s: not yet dethrottling call\n",__FUNCTION__);#endif						} else {#ifdef DEBUG_FLOW							log(LOG_DEBUG, "%s: dethrottling call\n",__FUNCTION__);#endif							if (c->dethrottle)								deschedule(c->dethrottle);							c->dethrottle=NULL;							c->throttle = 0;						}					} */                    c->data_rec_seq_num--;                    return 0;                }                else                {                    log (LOG_DEBUG, "%s: payload too small!\n", __FUNCTION__);                    return -EINVAL;                }            }            else            {                if (debug_tunnel)                    log (LOG_DEBUG, "%s: unable to expand payload!\n",                         __FUNCTION__);                return -EINVAL;            }        }        else        {            log (LOG_DEBUG, "%s: invalid payload packet!\n", __FUNCTION__);            return -EINVAL;        }    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -