Beispiel #1
0
struct call *get_call (int tunnel, int call, unsigned int addr, int port)
{
    /*
     * Figure out which call struct should handle this. 
     * If we have tunnel and call ID's then they are unique.
     * Otherwise, if the tunnel is 0, look for an existing connection
     * or create a new tunnel.
     */
    struct tunnel *st;
    struct call *sc;
    if (tunnel)
    {
        st = tunnels.head;
        while (st)
        {
            if (st->ourtid == tunnel)
            {
                if (call)
                {
                    sc = st->call_head;
                    while (sc)
                    {
                        if (sc->ourcid == call)
                            return sc;
                        sc = sc->next;
                    }
                    l2tp_log (LOG_DEBUG, "%s: can't find call %d in tunnel %d\n",
                         __FUNCTION__, call, tunnel);
                    return NULL;
                }
                else
                {
                    return st->self;
                }
            }
            st = st->next;
        }
        l2tp_log (LOG_DEBUG, "%s:can't find tunnel %d\n", __FUNCTION__, tunnel);
        return NULL;
    }
    else
    {
#ifdef USE_KERNEL
        struct l2tp_tunnel_opts to;
#endif
        /* You can't specify a call number if you haven't specified
           a tunnel silly! */

        if (call)
        {
            l2tp_log (LOG_WARN,
                 "%s: call ID specified, but no tunnel ID specified.  tossing.\n",
                 __FUNCTION__);
            return NULL;
        }
        /*
         * Well, nothing appropriate...  Let's add a new tunnel, if
         * we are not at capacity.
         */
        if (debug_tunnel)
        {
            l2tp_log (LOG_DEBUG,
                 "%s: allocating new tunnel for host %s, port %d.\n",
                 __FUNCTION__, IPADDY (addr), ntohs (port));
        }
        if (!(st = new_tunnel ()))
        {
            l2tp_log (LOG_WARN,
                 "%s: unable to allocate new tunnel for host %s, port %d.\n",
                 __FUNCTION__, IPADDY (addr), ntohs (port));
            return NULL;
        };
        st->peer.sin_family = AF_INET;
        st->peer.sin_port = port;
        bcopy (&addr, &st->peer.sin_addr, sizeof (addr));
#ifdef USE_KERNEL
        if (kernel_support)
        {
            /* Update kernel as to peer's location */
            to.ourtid = st->ourtid;
            ioctl (server_socket, L2TPIOCGETTUNOPTS, &to);
            bcopy (&st->peer, &to.peer, sizeof (st->peer));
            to.addrlen = sizeof (st->peer);
            ioctl (server_socket, L2TPIOCSETTUNOPTS, &to);
        }
#endif
        st->next = tunnels.head;
        tunnels.head = st;
        tunnels.count++;
        return st->self;
    }
}
struct call *get_call (int tunnel, int call,  unsigned int addr, int port,
                       IPsecSAref_t refme, IPsecSAref_t refhim)
{
    /*
     * Figure out which call struct should handle this.
     * If we have tunnel and call ID's then they are unique.
     * Otherwise, if the tunnel is 0, look for an existing connection
     * or create a new tunnel.
     */
    struct tunnel *st;
    struct call *sc;
    if (tunnel)
    {
        st = tunnels.head;
        while (st)
        {
            if (st->ourtid == tunnel &&
                    (gconfig.ipsecsaref==0 ||
                     (st->refhim == refhim
                      || refhim==IPSEC_SAREF_NULL
                      || st->refhim==IPSEC_SAREF_NULL)))
            {
                if (call)
                {
                    sc = st->call_head;
                    while (sc)
                    {
                        /* confirm that this is in fact a call with the right SA! */
                        if (sc->ourcid == call) return sc;
                        sc = sc->next;
                    }
                    l2tp_log (LOG_DEBUG, "%s: can't find call %d in tunnel %d\n (ref=%d/%d)",
                              __FUNCTION__, call, tunnel, refme, refhim);
                    return NULL;
                }
                else
                {
                    return st->self;
                }
            }
            st = st->next;
        }

        l2tp_log (LOG_DEBUG, "Can not find tunnel %u (refhim=%u)\n",
                  tunnel, refhim);
        return NULL;
    }
    else
    {
        /* You can't specify a call number if you haven't specified
           a tunnel silly! */

        if (call)
        {
            l2tp_log (LOG_WARNING,
                      "%s: call ID specified, but no tunnel ID specified.  tossing.\n",
                      __FUNCTION__);
            return NULL;
        }
        /*
         * Well, nothing appropriate...  Let's add a new tunnel, if
         * we are not at capacity.
         */
        if (gconfig.debug_tunnel)
        {
            l2tp_log (LOG_DEBUG,
                      "%s: allocating new tunnel for host %s, port %d.\n",
                      __FUNCTION__, IPADDY (addr), ntohs (port));
        }
        if (!(st = new_tunnel ()))
        {
            l2tp_log (LOG_WARNING,
                      "%s: unable to allocate new tunnel for host %s, port %d.\n",
                      __FUNCTION__, IPADDY (addr), ntohs (port));
            return NULL;
        };
        st->peer.sin_family = AF_INET;
        st->peer.sin_port = port;
        st->refme  = refme;
        st->refhim = refhim;
        // <-------  add for fix unable to connect to l2tp socket. By Jacky.Chen 2012.06.06
        st->u_fd = -1;
        st->m_fd = -1;
        // ------>
        bcopy (&addr, &st->peer.sin_addr, sizeof (addr));
        st->next = tunnels.head;
        tunnels.head = st;
        tunnels.count++;
        return st->self;
    }
}