static void overlord_dns_attack_detect(struct zsession *sess) { if (zcfg()->dns_attack_threshold) { uint64_t pps = spdm_calc(&sess->dns_speed); if (unlikely(pps >= zcfg()->dns_attack_threshold)) { if (!sess->is_dns_attack) { ZERO_LOG(LOG_WARNING, "DNS amplification attack begin detected: session %s, %" PRIu64 " pps", ipv4_to_str(sess->ip), pps); sess->is_dns_attack = true; } } else if (unlikely(sess->is_dns_attack)) { ZERO_LOG(LOG_WARNING, "DNS amplification attack end: session %s", ipv4_to_str(sess->ip)); sess->is_dns_attack = false; } } }
static void overlord_auth(struct zsession *sess) { uint64_t last_auth = atomic_load_explicit(&sess->last_auth, memory_order_acquire); uint64_t curr_time = ztime(false); if ((curr_time - last_auth) > zcfg()->session_auth_interval) { if (0 == last_auth) { zero_syslog(LOG_INFO, "New session %s", ipv4_to_str(htonl(sess->ip))); } session_authenticate(sess); atomic_store_explicit(&sess->last_auth, curr_time, memory_order_release); } }
/** * Server session. * - Authenticate sessions. * - Upload accounting. * - Remove inactive sessions. */ static void overlord_serve_session(struct zsession *sess) { uint64_t curr_time = ztime(true); zclock(true); // refresh // remove inactive, long duration or marked for deletion session uint32_t term_cause = 0; if (atomic_load_explicit(&sess->delete_flag, memory_order_acquire)) { term_cause = PW_ADMIN_RESET; zero_syslog(LOG_INFO, "Removed marked for deletion session %s", ipv4_to_str(htonl(sess->ip))); } else if (overlord_sess_is_idle_timeout(sess, curr_time)) { term_cause = PW_IDLE_TIMEOUT; zero_syslog(LOG_INFO, "Removed inactive session %s", ipv4_to_str(htonl(sess->ip))); } else if ((curr_time - sess->create_time) > atomic_load_explicit(&sess->max_duration, memory_order_acquire)) { term_cause = PW_SESSION_TIMEOUT; zero_syslog(LOG_INFO, "Removed long duration session %s", ipv4_to_str(htonl(sess->ip))); } if (term_cause) { if (sess->accounting_alive) { session_accounting(sess, PW_STATUS_STOP, term_cause); } session_remove(sess); } else { overlord_nat_cleanup(sess); overlord_apply_deferred_rules(sess); // authenticate session if (0 == sess->client->id) { overlord_auth(sess); } else if ((curr_time - atomic_load_explicit(&sess->last_acct, memory_order_acquire)) > atomic_load_explicit(&sess->acct_interval, memory_order_acquire)) { overlord_acct(sess); } } }
static void overlord_apply_deferred_rules(struct zsession *sess) { if (utarray_len(&sess->client->deferred_rules)) { struct zcrules parsed_rules; uint64_t curr_clock = zclock(false); pthread_spin_lock(&sess->client->lock); crules_init(&parsed_rules); while (utarray_back(&sess->client->deferred_rules)) { struct zrule_deferred *rule = *(struct zrule_deferred **) utarray_back(&sess->client->deferred_rules); if (rule->when > curr_clock) { break; } if (0 != crules_parse(&parsed_rules, rule->rule)) { zero_syslog(LOG_INFO, "Failed to parse deferred rule '%s' for client %s", rule->rule, ipv4_to_str(htonl(sess->ip))); } else { zero_syslog(LOG_INFO, "Applying deferred rule '%s' for client %s", rule->rule, ipv4_to_str(htonl(sess->ip))); } free(rule->rule); free(rule); utarray_pop_back(&sess->client->deferred_rules); } pthread_spin_unlock(&sess->client->lock); client_apply_rules(sess->client, &parsed_rules); crules_free(&parsed_rules); } }
/** @brief Open and configure the TAP device for packet read/write. * * This routine creates the interface via the tuntap driver then uses ifconfig * to configure address/mask and MTU. * * @param device - [inout] a device info holder object * @param dev - user-defined name for the new iface, * if NULL system will assign a name * @param device_ip - address of iface * @param device_mask - netmask for device_ip * @param mtu - MTU for device_ip * * @return - negative value on error * - non-negative file-descriptor on success */ int tuntap_open(tuntap_dev_t *device, ip_mode_t ip_mode) //char *dev, /* user-definable interface name, eg. edge0 */ //const char *address_mode, /* static or dhcp */ //char *device_ip, //char *device_mask, //const char *device_mac, //int mtu) { char *tuntap_device = "/dev/net/tun"; #define N2N_LINUX_SYSTEMCMD_SIZE 128 char buf[N2N_LINUX_SYSTEMCMD_SIZE]; struct ifreq ifr; int rc; //TODO ipstr_t ipstr; device->fd = open(tuntap_device, O_RDWR); if (device->fd < 0) { traceEvent(TRACE_ERROR, "Unable to open TUN/TAP device: ioctl() [%s][%d]\n", strerror(errno), errno); return -1; } traceEvent(TRACE_NORMAL, "Succesfully open %s\n", tuntap_device); memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; /* Want a TAP device for layer 2 frames. */ strncpy(ifr.ifr_name, device->dev_name, IFNAMSIZ); rc = ioctl(device->fd, TUNSETIFF, (void *) &ifr); if (rc < 0) { traceError("ioctl() [%s][%d]\n", strerror(errno), rc); close(device->fd); return -1; } /* Store the device name for later reuse */ strncpy(device->dev_name, ifr.ifr_name, MIN(IFNAMSIZ, N2N_IFNAMSIZ)); if ( !is_empty_mac(device->mac_addr) ) { /* Set the hw address before bringing the if up. */ macstr_t macstr; snprintf(buf, sizeof(buf), "/sbin/ifconfig %s hw ether %s", ifr.ifr_name, mac2str(macstr, device->mac_addr)); system(buf); traceInfo("Setting MAC: %s", buf); } ipv4_to_str(ipstr, sizeof(ipstr_t), (const uint8_t *) &device->ip_addr);//TODO make array if (ip_mode == N2N_IPM_DHCP) { snprintf(buf, sizeof(buf), "/sbin/ifconfig %s %s mtu %d up", ifr.ifr_name, ipstr, device->mtu); } else { ipstr_t maskstr; strcpy((char *) maskstr, inet_ntoa( *( (struct in_addr *) &device->device_mask) ));//TODO //intoa(device->device_mask, maskstr, sizeof(maskstr)); snprintf(buf, sizeof(buf), "/sbin/ifconfig %s %s netmask %s mtu %d up", ifr.ifr_name, ipstr, maskstr, device->mtu); } traceInfo("Bringing up: %s", buf); system(buf); //device->ip_addr = inet_addr(device_ip); //device->device_mask = inet_addr(device_mask); read_mac(device->dev_name, device->mac_addr); return (device->fd); }