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

📄 network.c

📁 第二层隧道模块l2tp源码,开发环境为linux
💻 C
📖 第 1 页 / 共 2 页
字号:
            (struct sockaddr *) &buf->peer, sizeof (buf->peer));}void network_thread (){    /*     * We loop forever waiting on either data from the ppp drivers or from     * our network socket.  Control handling is no longer done here.     */    int fromlen;                /* Length of the address */    int tunnel, call;           /* Tunnel and call */    int recvsize;               /* Length of data received */    struct buffer *buf;         /* Payload buffer */    struct call *c, *sc;        /* Call to send this off to */    struct tunnel *st;          /* Tunnel */    fd_set readfds;             /* Descriptors to watch for reading */    int max;                    /* Highest fd */    struct timeval tv;          /* Timeout for select */    /* This one buffer can be recycled for everything except control packets */    buf = new_buf (MAX_RECV_SIZE);    for (;;)    {        /*           * First, let's send out any outgoing packets that are waiting on us.           * xmit_udp should only           * contain control packets in the unthreaded version!         */        max = 0;        FD_ZERO (&readfds);        st = tunnels.head;        while (st)        {            if (st->self->needclose ^ st->self->closing)            {                if (debug_tunnel)                    log (LOG_DEBUG, "%S: closing down tunnel %d\n",                         __FUNCTION__, st->ourtid);                call_close (st->self);                /* Reset the while loop                   and check for NULL */                st = tunnels.head;                if (!st)                    break;                continue;            }            sc = st->call_head;            while (sc)            {                if (sc->needclose ^ sc->closing)                {                    call_close (sc);                    sc = st->call_head;                    if (!sc)                        break;                    continue;                }                if (sc->fd > -1)                {/*					if (!sc->throttle && !sc->needclose && !sc->closing) { */                    if (!sc->needclose && !sc->closing)                    {                        if (sc->fd > max)                            max = sc->fd;                        FD_SET (sc->fd, &readfds);                    }                }                sc = sc->next;            }            st = st->next;        }        FD_SET (server_socket, &readfds);        if (server_socket > max)            max = server_socket;        FD_SET (control_fd, &readfds);        if (control_fd > max)            max = control_fd;        tv.tv_sec = 1;        tv.tv_usec = 0;        schedule_unlock ();        select (max + 1, &readfds, NULL, NULL, NULL);        schedule_lock ();        if (FD_ISSET (control_fd, &readfds))        {            do_control ();        }        if (FD_ISSET (server_socket, &readfds))        {            /*             * Okay, now we're ready for reading and processing new data.             */            recycle_buf (buf);            /* Reserve space for expanding payload packet headers */            buf->start += PAYLOAD_BUF;            buf->len -= PAYLOAD_BUF;            fromlen = sizeof (from);            recvsize =                recvfrom (server_socket, buf->start, buf->len, 0,                          (struct sockaddr *) &from, &fromlen);            if (recvsize < MIN_PAYLOAD_HDR_LEN)            {                if (recvsize < 0)                {                    if (errno != EAGAIN)                        log (LOG_WARN,                             "%s: recvfrom returned error %d (%s)\n",                             __FUNCTION__, errno, strerror (errno));                }                else                {                    log (LOG_WARN, "%s: received too small a packet\n",                         __FUNCTION__);                }            }            else            {                buf->len = recvsize;                fix_hdr (buf->start);                extract (buf->start, &tunnel, &call);                if (debug_network)                {                    log (LOG_DEBUG, "%s: recv packet from %s, size = %d,tunnel = %d, call = %d\n", __FUNCTION__, inet_ntoa (from.sin_addr), recvsize, tunnel, call);                }                if (packet_dump)                {                    do_packet_dump (buf);                }                if (!                    (c =                     get_call (tunnel, call, from.sin_addr.s_addr,                               from.sin_port)))                {                    if ((c =                         get_tunnel (tunnel, from.sin_addr.s_addr,                                     from.sin_port)))                    {                        /*                         * It is theoretically possible that we could be sent                         * a control message (say a StopCCN) on a call that we                         * have already closed or some such nonsense.  To prevent                         * this from closing the tunnel, if we get a call on a valid                         * tunnel, but not with a valid CID, we'll just send a ZLB                         * to ack receiving the packet.                         */                        if (debug_tunnel)                            log (LOG_DEBUG,                                 "%s: no such call %d on tunnel %d.  Sending special ZLB\n",                                 __FUNCTION__);                        handle_special (buf, c, call);                    }                    else                        log (LOG_DEBUG,                             "%s: unable to find call or tunnel to handle packet.  call = %d, tunnel = %d Dumping.\n",                             __FUNCTION__, call, tunnel);                }                else                {                    buf->peer = from;                    /* Handle the packet */                    c->container->chal_us.vector = NULL;                    if (handle_packet (buf, c->container, c))                    {                        if (debug_tunnel)                            log (LOG_DEBUG, "%s: bad packet\n", __FUNCTION__);                    };                    if (c->cnu)                    {                        /* Send Zero Byte Packet */                        control_zlb (buf, c->container, c);                        c->cnu = 0;                    }                }            }        };        st = tunnels.head;        while (st)        {            sc = st->call_head;            while (sc)            {                if ((sc->fd >= 0) && FD_ISSET (sc->fd, &readfds))                {                    /* Got some payload to send */                    int result;                    recycle_payload (buf, sc->container->peer);#ifdef DEBUG_FLOW_MORE                    log (LOG_DEBUG, "%s: rws = %d, pSs = %d, pLr = %d\n",                         __FUNCTION__, sc->rws, sc->pSs, sc->pLr);#endif/*					if ((sc->rws>0) && (sc->pSs > sc->pLr + sc->rws) && !sc->rbit) {#ifdef DEBUG_FLOW						log(LOG_DEBUG, "%s: throttling payload (call = %d, tunnel = %d, Lr = %d, Ss = %d, rws = %d)!\n",__FUNCTION__,								 sc->cid, sc->container->tid, sc->pLr, sc->pSs, sc->rws); #endif						sc->throttle = -1;						We unthrottle in handle_packet if we get a payload packet, 						valid or ZLB, but we also schedule a dethrottle in which						case the R-bit will be set						FIXME: Rate Adaptive timeout? 												tv.tv_sec = 2;						tv.tv_usec = 0;						sc->dethrottle = schedule(tv, dethrottle, sc); 										} else *//*					while ((result=read_packet(buf,sc->fd,sc->frame & SYNC_FRAMING))>0) { */                    while ((result =                            read_packet (buf, sc->fd, SYNC_FRAMING)) > 0)                    {                        add_payload_hdr (sc->container, sc, buf);                        if (packet_dump)                        {                            do_packet_dump (buf);                        }                        sc->prx = sc->data_rec_seq_num;                        if (sc->zlb_xmit)                        {                            deschedule (sc->zlb_xmit);                            sc->zlb_xmit = NULL;                        }                        sc->tx_bytes += buf->len;                        sc->tx_pkts++;                        udp_xmit (buf);                        recycle_payload (buf, sc->container->peer);                    }                    if (result != 0)                    {                        log (LOG_WARN,                             "%s: tossing read packet, error = %s (%d).  Closing call.\n",                             __FUNCTION__, strerror (-result), -result);                        strcpy (sc->errormsg, strerror (-result));                        sc->needclose = -1;                    }                }                sc = sc->next;            }            st = st->next;        }    }}

⌨️ 快捷键说明

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