void lac_hangup (int cid) { struct tunnel *t = tunnels.head; struct call *tmp; while (t) { tmp = t->call_head; while (tmp) { if (tmp->ourcid == cid) { l2tp_log (LOG_INFO, "%s :Hanging up call %d, Local: %d, Remote: %d\n", __FUNCTION__, tmp->serno, tmp->ourcid, tmp->cid); strcpy (tmp->errormsg, "Goodbye!"); if (tmp->pppd) kill_pppd(tmp->pppd); return; } tmp = tmp->next; } t = t->next; }; l2tp_log (LOG_DEBUG, "%s : No such call %d to hang up.\n", __FUNCTION__, cid); return; }
void destroy_call (struct call *c) { /* * Here, we unconditionally destroy a call. */ struct call *p; struct timeval tv; pid_t pid; /* * Close the tty */ if (c->fd > 0) close (c->fd); /* if (c->dethrottle) deschedule(c->dethrottle); */ if (c->zlb_xmit) deschedule (c->zlb_xmit); #ifdef IP_ALLOCATION if (c->addr) unreserve_addr (c->addr); #endif /* * Kill off pppd and wait for it to * return to us. This should only be called * in rare cases if pppd hasn't already died * voluntarily */ pid = c->pppd; if (pid) { /* Set c->pppd to zero to prevent recursion with child_handler */ c->pppd = 0; /* * There is a bug in some pppd versions where sending a SIGTERM * does not actually seem to kill pppd, and xl2tpd waits indefinately * using waitpid, not accepting any new connections either. Therefor * we now use some more force and send it a SIGKILL instead of SIGTERM. * One confirmed buggy version of pppd is ppp-2.4.2-6.4.RHEL4 * See http://bugs.xelerance.com/view.php?id=739 * * Sometimes pppd takes 7 sec to go down! We don't have that much time, * since all other calls are suspended while doing this. */ kill_pppd(pid); } if (c->container) { p = c->container->call_head; /* * Remove us from the call list, although * we might not actually be there */ if (p) { if (p == c) { c->container->call_head = c->next; c->container->count--; } else { while (p->next && (p->next != c)) p = p->next; if (p->next) { p->next = c->next; c->container->count--; } } } } if (c->lac) { c->lac->c = NULL; if (c->lac->redial && (c->lac->rtimeout > 0) && !c->lac->rsched && c->lac->active) { #ifdef DEBUG_MAGIC l2tp_log (LOG_DEBUG, "Will redial in %d seconds\n", c->lac->rtimeout); #endif tv.tv_sec = c->lac->rtimeout; tv.tv_usec = 0; c->lac->rsched = schedule (tv, magic_lac_dial, c->lac); } } free (c); }