/* reset timeout */ static void l2tp_ctrl_reset_timeout(l2tp_ctrl *_this) { int intvl; struct timeval tv0; L2TP_CTRL_ASSERT(_this != NULL); if (evtimer_initialized(&_this->ev_timeout)) evtimer_del(&_this->ev_timeout); switch (_this->state) { case L2TP_CTRL_STATE_CLEANUP_WAIT: intvl = 1; break; default: intvl = 2; break; } tv0.tv_usec = 0; tv0.tv_sec = intvl; if (!evtimer_initialized(&_this->ev_timeout)) evtimer_set(&_this->ev_timeout, l2tp_ctrl_timeout, _this); evtimer_add(&_this->ev_timeout, &tv0); }
/* * Process at least one key in the buffer and invoke tty->key_callback. Return * 0 if there are no further keys, or 1 if there could be more in the buffer. */ key_code tty_keys_next(struct tty *tty) { struct tty_key *tk; struct timeval tv; const char *buf; size_t len, size; cc_t bspace; int delay, expired = 0; key_code key; struct utf8_data ud; enum utf8_state more; u_int i; /* Get key buffer. */ buf = EVBUFFER_DATA(tty->event->input); len = EVBUFFER_LENGTH(tty->event->input); if (len == 0) return (0); log_debug("keys are %zu (%.*s)", len, (int) len, buf); /* Is this a mouse key press? */ switch (tty_keys_mouse(tty, buf, len, &size)) { case 0: /* yes */ key = KEYC_MOUSE; goto complete_key; case -1: /* no, or not valid */ break; case -2: /* yes, but we don't care. */ key = KEYC_MOUSE; goto discard_key; case 1: /* partial */ goto partial_key; } /* Look for matching key string and return if found. */ tk = tty_keys_find(tty, buf, len, &size); if (tk != NULL) { if (tk->next != NULL) goto partial_key; key = tk->key; goto complete_key; } /* Try to parse a key with an xterm-style modifier. */ switch (xterm_keys_find(buf, len, &size, &key)) { case 0: /* found */ goto complete_key; case -1: /* not found */ break; case 1: goto partial_key; } first_key: /* Is this a meta key? */ if (len >= 2 && buf[0] == '\033') { if (buf[1] != '\033') { key = buf[1] | KEYC_ESCAPE; size = 2; goto complete_key; } tk = tty_keys_find(tty, buf + 1, len - 1, &size); if (tk != NULL && (!expired || tk->next == NULL)) { size++; /* include escape */ if (tk->next != NULL) goto partial_key; key = tk->key; if (key != KEYC_NONE) key |= KEYC_ESCAPE; goto complete_key; } } /* Is this valid UTF-8? */ if ((more = utf8_open(&ud, (u_char)*buf) == UTF8_MORE)) { size = ud.size; if (len < size) { if (expired) goto discard_key; goto partial_key; } for (i = 1; i < size; i++) more = utf8_append(&ud, (u_char)buf[i]); if (more != UTF8_DONE) goto discard_key; key = utf8_combine(&ud); log_debug("UTF-8 key %.*s %#llx", (int)size, buf, key); goto complete_key; } /* No key found, take first. */ key = (u_char)*buf; size = 1; /* * Check for backspace key using termios VERASE - the terminfo * kbs entry is extremely unreliable, so cannot be safely * used. termios should have a better idea. */ bspace = tty->tio.c_cc[VERASE]; if (bspace != _POSIX_VDISABLE && key == bspace) key = KEYC_BSPACE; goto complete_key; partial_key: log_debug("partial key %.*s", (int) len, buf); /* If timer is going, check for expiration. */ if (tty->flags & TTY_TIMER) { if (evtimer_initialized(&tty->key_timer) && !evtimer_pending(&tty->key_timer, NULL)) { expired = 1; goto first_key; } return (0); } /* Get the time period. */ delay = options_get_number(global_options, "escape-time"); tv.tv_sec = delay / 1000; tv.tv_usec = (delay % 1000) * 1000L; /* Start the timer. */ if (event_initialized(&tty->key_timer)) evtimer_del(&tty->key_timer); evtimer_set(&tty->key_timer, tty_keys_callback, tty); evtimer_add(&tty->key_timer, &tv); tty->flags |= TTY_TIMER; return (0); complete_key: log_debug("complete key %.*s %#llx", (int)size, buf, key); /* Remove data from buffer. */ evbuffer_drain(tty->event->input, size); /* Remove key timer. */ if (event_initialized(&tty->key_timer)) evtimer_del(&tty->key_timer); tty->flags &= ~TTY_TIMER; /* Check for focus events. */ if (key == KEYC_FOCUS_OUT) { tty->client->flags &= ~CLIENT_FOCUSED; return (1); } else if (key == KEYC_FOCUS_IN) { tty->client->flags |= CLIENT_FOCUSED; return (1); } /* Fire the key. */ if (key != KEYC_NONE) server_client_handle_key(tty->client, key); return (1); discard_key: log_debug("discard key %.*s %#llx", (int)size, buf, key); /* Remove data from buffer. */ evbuffer_drain(tty->event->input, size); return (1); }
/* * Process at least one key in the buffer and invoke tty->key_callback. Return * 0 if there are no further keys, or 1 if there could be more in the buffer. */ int tty_keys_next(struct tty *tty) { struct tty_key *tk; struct timeval tv; const char *buf; size_t len, size; cc_t bspace; int key, delay; buf = EVBUFFER_DATA(tty->event->input); len = EVBUFFER_LENGTH(tty->event->input); if (len == 0) return (0); log_debug("keys are %zu (%.*s)", len, (int) len, buf); /* If a normal key, return it. */ if (*buf != '\033') { key = (u_char) *buf; evbuffer_drain(tty->event->input, 1); /* * Check for backspace key using termios VERASE - the terminfo * kbs entry is extremely unreliable, so cannot be safely * used. termios should have a better idea. */ bspace = tty->tio.c_cc[VERASE]; if (bspace != _POSIX_VDISABLE && key == bspace) key = KEYC_BSPACE; goto handle_key; } /* Is this device attributes response? */ switch (tty_keys_device(tty, buf, len, &size)) { case 0: /* yes */ evbuffer_drain(tty->event->input, size); key = KEYC_NONE; goto handle_key; case -1: /* no, or not valid */ break; case 1: /* partial */ goto partial_key; } /* Is this a mouse key press? */ switch (tty_keys_mouse(tty, buf, len, &size)) { case 0: /* yes */ evbuffer_drain(tty->event->input, size); key = KEYC_MOUSE; goto handle_key; case -1: /* no, or not valid */ break; case 1: /* partial */ goto partial_key; } /* Try to parse a key with an xterm-style modifier. */ switch (xterm_keys_find(buf, len, &size, &key)) { case 0: /* found */ evbuffer_drain(tty->event->input, size); goto handle_key; case -1: /* not found */ break; case 1: goto partial_key; } /* Look for matching key string and return if found. */ tk = tty_keys_find(tty, buf + 1, len - 1, &size); if (tk != NULL) { key = tk->key; goto found_key; } /* Skip the escape. */ buf++; len--; /* Is there a normal key following? */ if (len != 0 && *buf != '\033') { key = *buf | KEYC_ESCAPE; evbuffer_drain(tty->event->input, 2); goto handle_key; } /* Or a key string? */ if (len > 1) { tk = tty_keys_find(tty, buf + 1, len - 1, &size); if (tk != NULL) { key = tk->key | KEYC_ESCAPE; size++; /* include escape */ goto found_key; } } /* Escape and then nothing useful - fall through. */ partial_key: /* * Escape but no key string. If have already seen an escape and the * timer has expired, give up waiting and send the escape. */ if ((tty->flags & TTY_ESCAPE) && evtimer_initialized(&tty->key_timer) && !evtimer_pending(&tty->key_timer, NULL)) { evbuffer_drain(tty->event->input, 1); key = '\033'; goto handle_key; } /* Fall through to start the timer. */ start_timer: /* If already waiting for timer, do nothing. */ if (evtimer_initialized(&tty->key_timer) && evtimer_pending(&tty->key_timer, NULL)) return (0); /* Start the timer and wait for expiry or more data. */ delay = options_get_number(&global_options, "escape-time"); tv.tv_sec = delay / 1000; tv.tv_usec = (delay % 1000) * 1000L; if (event_initialized(&tty->key_timer)) evtimer_del(&tty->key_timer); evtimer_set(&tty->key_timer, tty_keys_callback, tty); evtimer_add(&tty->key_timer, &tv); tty->flags |= TTY_ESCAPE; return (0); found_key: if (tk->next != NULL) { /* Partial key. Start the timer if not already expired. */ if (!(tty->flags & TTY_ESCAPE)) goto start_timer; /* Otherwise, if no key, send the escape alone. */ if (tk->key == KEYC_NONE) goto partial_key; /* Or fall through to send the partial key found. */ } evbuffer_drain(tty->event->input, size + 1); goto handle_key; handle_key: if (event_initialized(&tty->key_timer)) evtimer_del(&tty->key_timer); if (key != KEYC_NONE) server_client_handle_key(tty->client, key); tty->flags &= ~TTY_ESCAPE; return (1); }
/* * Process at least one key in the buffer and invoke tty->key_callback. Return * 0 if there are no further keys, or 1 if there could be more in the buffer. */ int tty_keys_next(struct tty *tty) { struct tty_key *tk; struct timeval tv; const char *buf; size_t len, size; cc_t bspace; int key, delay; /* Get key buffer. */ buf = EVBUFFER_DATA(tty->event->input); len = EVBUFFER_LENGTH(tty->event->input); if (len == 0) return (0); log_debug("keys are %zu (%.*s)", len, (int) len, buf); /* Is this device attributes response? */ switch (tty_keys_device(tty, buf, len, &size)) { case 0: /* yes */ key = KEYC_NONE; goto complete_key; case -1: /* no, or not valid */ break; case 1: /* partial */ goto partial_key; } /* Is this a mouse key press? */ switch (tty_keys_mouse(tty, buf, len, &size)) { case 0: /* yes */ key = KEYC_MOUSE; goto complete_key; case -1: /* no, or not valid */ break; case 1: /* partial */ goto partial_key; } /* Try to parse a key with an xterm-style modifier. */ switch (xterm_keys_find(buf, len, &size, &key)) { case 0: /* found */ goto complete_key; case -1: /* not found */ break; case 1: goto partial_key; } /* Look for matching key string and return if found. */ tk = tty_keys_find(tty, buf, len, &size); if (tk != NULL) { if (tk->next != NULL) goto partial_key; key = tk->key; goto complete_key; } /* Is this a meta key? */ if (len >= 2 && buf[0] == '\033') { if (buf[1] != '\033') { key = buf[1] | KEYC_ESCAPE; size = 2; goto complete_key; } tk = tty_keys_find(tty, buf + 1, len - 1, &size); if (tk != NULL) { size++; /* include escape */ if (tk->next != NULL) goto partial_key; key = tk->key; if (key != KEYC_NONE) key |= KEYC_ESCAPE; goto complete_key; } } first_key: /* No key found, take first. */ key = (u_char) *buf; size = 1; /* * Check for backspace key using termios VERASE - the terminfo * kbs entry is extremely unreliable, so cannot be safely * used. termios should have a better idea. */ bspace = tty->tio.c_cc[VERASE]; if (bspace != _POSIX_VDISABLE && key == bspace) key = KEYC_BSPACE; goto complete_key; partial_key: log_debug("partial key %.*s", (int) len, buf); /* If timer is going, check for expiration. */ if (tty->flags & TTY_TIMER) { if (evtimer_initialized(&tty->key_timer) && !evtimer_pending(&tty->key_timer, NULL)) goto first_key; return (0); } /* Get the time period. */ delay = options_get_number(&global_options, "escape-time"); tv.tv_sec = delay / 1000; tv.tv_usec = (delay % 1000) * 1000L; /* Start the timer. */ if (event_initialized(&tty->key_timer)) evtimer_del(&tty->key_timer); evtimer_set(&tty->key_timer, tty_keys_callback, tty); evtimer_add(&tty->key_timer, &tv); tty->flags |= TTY_TIMER; return (0); complete_key: log_debug("complete key %.*s %#x", (int) size, buf, key); /* Remove data from buffer. */ evbuffer_drain(tty->event->input, size); /* Remove key timer. */ if (event_initialized(&tty->key_timer)) evtimer_del(&tty->key_timer); tty->flags &= ~TTY_TIMER; /* Fire the key. */ if (key != KEYC_NONE) server_client_handle_key(tty->client, key); return (1); }
/* * Process at least one key in the buffer and invoke tty->key_callback. Return * 0 if there are no further keys, or 1 if there could be more in the buffer. */ key_code tty_keys_next(struct tty *tty) { struct timeval tv; const char *buf; size_t len, size; cc_t bspace; int delay, expired = 0, n; key_code key; /* Get key buffer. */ buf = EVBUFFER_DATA(tty->event->input); len = EVBUFFER_LENGTH(tty->event->input); if (len == 0) return (0); log_debug("keys are %zu (%.*s)", len, (int)len, buf); /* Is this a mouse key press? */ switch (tty_keys_mouse(tty, buf, len, &size)) { case 0: /* yes */ key = KEYC_MOUSE; goto complete_key; case -1: /* no, or not valid */ break; case -2: /* yes, but we don't care. */ key = KEYC_MOUSE; goto discard_key; case 1: /* partial */ goto partial_key; } first_key: /* Handle keys starting with escape. */ if (*buf == '\033') { /* Look for a key without the escape. */ n = tty_keys_next1(tty, buf + 1, len - 1, &key, &size, expired); if (n == 0) { /* found */ key |= KEYC_ESCAPE; size++; goto complete_key; } if (n == 1) /* partial */ goto partial_key; } /* Try to lookup key. */ n = tty_keys_next1(tty, buf, len, &key, &size, expired); if (n == 0) /* found */ goto complete_key; if (n == 1) goto partial_key; /* Is this an an xterm(1) key? */ n = xterm_keys_find(buf, len, &size, &key); if (n == 0) goto complete_key; if (n == 1 && !expired) goto partial_key; /* * At this point, we know the key is not partial (with or without * escape). So pass it through even if the timer has not expired. */ if (*buf == '\033' && len >= 2) { key = (u_char)buf[1] | KEYC_ESCAPE; size = 2; } else { key = (u_char)buf[0]; size = 1; } goto complete_key; partial_key: log_debug("partial key %.*s", (int)len, buf); /* If timer is going, check for expiration. */ if (tty->flags & TTY_TIMER) { if (evtimer_initialized(&tty->key_timer) && !evtimer_pending(&tty->key_timer, NULL)) { expired = 1; goto first_key; } return (0); } /* Get the time period. */ delay = options_get_number(global_options, "escape-time"); tv.tv_sec = delay / 1000; tv.tv_usec = (delay % 1000) * 1000L; /* Start the timer. */ if (event_initialized(&tty->key_timer)) evtimer_del(&tty->key_timer); evtimer_set(&tty->key_timer, tty_keys_callback, tty); evtimer_add(&tty->key_timer, &tv); tty->flags |= TTY_TIMER; return (0); complete_key: log_debug("complete key %.*s %#llx", (int)size, buf, key); /* * Check for backspace key using termios VERASE - the terminfo * kbs entry is extremely unreliable, so cannot be safely * used. termios should have a better idea. */ bspace = tty->tio.c_cc[VERASE]; if (bspace != _POSIX_VDISABLE && (key & KEYC_MASK_KEY) == bspace) key = (key & KEYC_MASK_MOD) | KEYC_BSPACE; /* Remove data from buffer. */ evbuffer_drain(tty->event->input, size); /* Remove key timer. */ if (event_initialized(&tty->key_timer)) evtimer_del(&tty->key_timer); tty->flags &= ~TTY_TIMER; /* Check for focus events. */ if (key == KEYC_FOCUS_OUT) { tty->client->flags &= ~CLIENT_FOCUSED; return (1); } else if (key == KEYC_FOCUS_IN) { tty->client->flags |= CLIENT_FOCUSED; return (1); } /* Fire the key. */ if (key != KEYC_UNKNOWN) server_client_handle_key(tty->client, key); return (1); discard_key: log_debug("discard key %.*s %#llx", (int)size, buf, key); /* Remove data from buffer. */ evbuffer_drain(tty->event->input, size); return (1); }
/** * Initialize the npppd_ppp instance * Set npppd_ppp#mru and npppd_ppp#phy_label before call this function. */ int ppp_init(npppd *pppd, npppd_ppp *_this) { PPP_ASSERT(_this != NULL); PPP_ASSERT(strlen(_this->phy_label) > 0); _this->id = -1; _this->ifidx = -1; _this->has_acf = 1; _this->recv_packet = ppp_recv_packet; _this->id = ppp_seq++; _this->pppd = pppd; lcp_init(&_this->lcp, _this); _this->mru = ppp_config_int(_this, "lcp.mru", DEFAULT_MRU); if (_this->outpacket_buf == NULL) { _this->outpacket_buf = malloc(_this->mru + 64); if (_this->outpacket_buf == NULL){ log_printf(LOG_ERR, "malloc() failed in %s(): %m", __func__); return -1; } } _this->adjust_mss = ppp_config_str_equal(_this, "ip.adjust_mss", "true", 0); #ifdef USE_NPPPD_PIPEX _this->use_pipex = ppp_config_str_equal(_this, "pipex.enabled", "true", 1); #endif /* load the logging configuration */ _this->log_dump_in = ppp_config_str_equal(_this, "log.in.pktdump", "true", 0); _this->log_dump_out = ppp_config_str_equal(_this, "log.out.pktdump", "true", 0); _this->ingress_filter = ppp_config_str_equal(_this, "ingress_filter", "true", 0); #ifdef USE_NPPPD_MPPE mppe_init(&_this->mppe, _this); #endif ccp_init(&_this->ccp, _this); ipcp_init(&_this->ipcp, _this); pap_init(&_this->pap, _this); chap_init(&_this->chap, _this); /* load the idle timer configuration */ _this->timeout_sec = ppp_config_int(_this, "idle_timeout", 0); if (!evtimer_initialized(&_this->idle_event)) evtimer_set(&_this->idle_event, ppp_idle_timeout, _this); _this->auth_timeout = ppp_config_int(_this, "auth.timeout", DEFAULT_AUTH_TIMEOUT); _this->lcp.echo_interval = ppp_config_int(_this, "lcp.echo_interval", DEFAULT_LCP_ECHO_INTERVAL); _this->lcp.echo_max_retries = ppp_config_int(_this, "lcp.echo_max_retries", DEFAULT_LCP_ECHO_MAX_RETRIES); _this->lcp.echo_retry_interval = ppp_config_int(_this, "lcp.echo_retry_interval", DEFAULT_LCP_ECHO_RETRY_INTERVAL); return 0; }