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; } }