/** Read a 'packet' of data from a connection and process it. Read in * 8k chunks to give a better performance rating (for server * connections). Do some tricky stuff for client connections to make * sure they don't do any flooding >:-) -avalon * @param cptr Client from which to read data. * @param socket_ready If non-zero, more data can be read from the client's socket. * @return Positive number on success, zero on connection-fatal failure, negative * if user is killed. */ static int read_packet(struct Client *cptr, int socket_ready) { unsigned int dolen = 0; unsigned int length = 0; if (socket_ready && !(IsUser(cptr) && !IsOper(cptr) && DBufLength(&(cli_recvQ(cptr))) > feature_int(FEAT_CLIENT_FLOOD))) { switch (os_recv_nonb(cli_fd(cptr), readbuf, sizeof(readbuf), &length)) { case IO_SUCCESS: if (length) { cli_lasttime(cptr) = CurrentTime; ClearPingSent(cptr); ClrFlag(cptr, FLAG_NONL); if (cli_lasttime(cptr) > cli_since(cptr)) cli_since(cptr) = cli_lasttime(cptr); } break; case IO_BLOCKED: break; case IO_FAILURE: cli_error(cptr) = errno; /* SetFlag(cptr, FLAG_DEADSOCKET); */ return 0; } } /* * For server connections, we process as many as we can without * worrying about the time of day or anything :) */ if (length > 0 && IsServer(cptr)) return server_dopacket(cptr, readbuf, length); else if (length > 0 && (IsHandshake(cptr) || IsConnecting(cptr))) return connect_dopacket(cptr, readbuf, length); else { /* * Before we even think of parsing what we just read, stick * it on the end of the receive queue and do it when its * turn comes around. */ if (length > 0 && dbuf_put(&(cli_recvQ(cptr)), readbuf, length) == 0) return exit_client(cptr, cptr, &me, "dbuf_put fail"); if (IsUser(cptr)) { if (DBufLength(&(cli_recvQ(cptr))) > feature_int(FEAT_CLIENT_FLOOD) && !IsOper(cptr)) return exit_client(cptr, cptr, &me, "Excess Flood"); } while (DBufLength(&(cli_recvQ(cptr))) && !NoNewLine(cptr) && (IsTrusted(cptr) || cli_since(cptr) - CurrentTime < 10)) { dolen = dbuf_getmsg(&(cli_recvQ(cptr)), cli_buffer(cptr), BUFSIZE); /* * Devious looking...whats it do ? well..if a client * sends a *long* message without any CR or LF, then * dbuf_getmsg fails and we pull it out using this * loop which just gets the next 512 bytes and then * deletes the rest of the buffer contents. * -avalon */ if (dolen == 0) { if (DBufLength(&(cli_recvQ(cptr))) < 510) SetFlag(cptr, FLAG_NONL); else { /* More than 512 bytes in the line - drop the input and yell * at the client. */ DBufClear(&(cli_recvQ(cptr))); send_reply(cptr, ERR_INPUTTOOLONG); } } else if (client_dopacket(cptr, dolen) == CPTR_KILLED) return CPTR_KILLED; /* * If it has become registered as a Server * then skip the per-message parsing below. */ if (IsHandshake(cptr) || IsServer(cptr)) { while (-1) { dolen = dbuf_get(&(cli_recvQ(cptr)), readbuf, sizeof(readbuf)); if (dolen <= 0) return 1; else if (dolen == 0) { if (DBufLength(&(cli_recvQ(cptr))) < 510) SetFlag(cptr, FLAG_NONL); else DBufClear(&(cli_recvQ(cptr))); } else if ((IsServer(cptr) && server_dopacket(cptr, readbuf, dolen) == CPTR_KILLED) || (!IsServer(cptr) && connect_dopacket(cptr, readbuf, dolen) == CPTR_KILLED)) return CPTR_KILLED; } } } /* If there's still data to process, wait 2 seconds first */ if (DBufLength(&(cli_recvQ(cptr))) && !NoNewLine(cptr) && !t_onqueue(&(cli_proc(cptr)))) { Debug((DEBUG_LIST, "Adding client process timer for %C", cptr)); cli_freeflag(cptr) |= FREEFLAG_TIMER; timer_add(&(cli_proc(cptr)), client_timer_callback, cli_connect(cptr), TT_RELATIVE, 2); } } return 1; }
void init_app_timers(void) { timer_add(&screenTimer, 50, &screen_timer_callback, NULL ); timer_add(&encTimer, 50, &enc_timer_callback, NULL ); }
static void fini_profiler(ClipMachine * ClipMachineMemory) { Coll coll; int r, i; FILE *out; char path[256]; struct timeval total; unsigned long ms, us; init_profiler(ClipMachineMemory); /* generate report here */ init_Coll(&coll, 0, cmp_profile_out); snprintf(path, sizeof(path), "%s.pro", _clip_progname); out = fopen(path, "w"); if (!out) out = stderr; for (r = HashTable_first(ClipMachineMemory->profiler); r; r = HashTable_next(ClipMachineMemory->profiler)) { ProfileBucket *bp = (ProfileBucket *) HashTable_current(ClipMachineMemory->profiler); insert_Coll(&coll, bp); } total.tv_sec = 0; total.tv_usec = 0; for (i = 0; i < coll.count_of_Coll; i++) { ProfileBucket *bp = (ProfileBucket *) coll.items_of_Coll[i]; struct timeval tv; if (!bp->procname_of_ProfileBucket[0] && !bp->filename_of_ProfileBucket[0]) continue; ms = bp->timeval_self_of_ProfileBucket.tv_sec * 1000 + bp->timeval_self_of_ProfileBucket.tv_usec / 1000; us = bp->timeval_self_of_ProfileBucket.tv_usec % 1000; tv = total; timer_add(&tv, &bp->timeval_self_of_ProfileBucket, &total); fprintf(out, "%18s %-13s %8ld calls %8lu.%03lu ms\n", bp->procname_of_ProfileBucket, bp->filename_of_ProfileBucket, bp->callno_of_ProfileBucket, ms, us); } ms = total.tv_sec * 1000 + total.tv_usec / 1000; us = total.tv_usec % 1000; fprintf(out, "---------------------------------\n"); fprintf(out, "total registered %8lu.%03lu ms\n", ms, us); destroy_Coll(&coll); if (out != stderr) fclose(out); }
/* initialize ratelimit module */ static int mod_init(void) { if(rpc_register_array(rpc_methods)!=0) { LM_ERR("failed to register RPC commands\n"); return -1; } if(register_mi_mod(exports.name, mi_cmds)!=0) { LM_ERR("failed to register MI commands\n"); return -1; } if(pl_init_htable(16)<0) { LM_ERR("could not allocate pipes htable\n"); return -1; } if(pl_init_db()<0) { LM_ERR("could not load pipes description\n"); return -1; } /* register timer to reset counters */ if ((pl_timer = timer_alloc()) == NULL) { LM_ERR("could not allocate timer\n"); return -1; } timer_init(pl_timer, pl_timer_handle, 0, F_TIMER_FAST); timer_add(pl_timer, MS_TO_TICKS(1500)); /* Start it after 1500ms */ /* bind the SL API */ if (sl_load_api(&slb)!=0) { LM_ERR("cannot bind to SL API\n"); return -1; } network_load_value = shm_malloc(sizeof(int)); if (network_load_value==NULL) { LM_ERR("oom for network_load_value\n"); return -1; } load_value = shm_malloc(sizeof(double)); if (load_value==NULL) { LM_ERR("oom for load_value\n"); return -1; } load_source = shm_malloc(sizeof(int)); if (load_source==NULL) { LM_ERR("oom for load_source\n"); return -1; } pid_kp = shm_malloc(sizeof(double)); if (pid_kp==NULL) { LM_ERR("oom for pid_kp\n"); return -1; } pid_ki = shm_malloc(sizeof(double)); if (pid_ki==NULL) { LM_ERR("oom for pid_ki\n"); return -1; } pid_kd = shm_malloc(sizeof(double)); if (pid_kd==NULL) { LM_ERR("oom for pid_kd\n"); return -1; } _pl_pid_setpoint = shm_malloc(sizeof(double)); if (_pl_pid_setpoint==NULL) { LM_ERR("oom for pid_setpoint\n"); return -1; } drop_rate = shm_malloc(sizeof(int)); if (drop_rate==NULL) { LM_ERR("oom for drop_rate\n"); return -1; } *network_load_value = 0; *load_value = 0.0; *load_source = load_source_mp; *pid_kp = 0.0; *pid_ki = -25.0; *pid_kd = 0.0; *_pl_pid_setpoint = 0.01 * (double)_pl_cfg_setpoint; *drop_rate = 0; pl_drop_reason.len = strlen(pl_drop_reason.s); return 0; }
static int sasyncd_run(pid_t ppid) { struct timeval *timeout, tv; fd_set *rfds, *wfds; size_t fdsetsize; int maxfd, n; n = getdtablesize(); fdsetsize = howmany(n, NFDBITS) * sizeof(fd_mask); rfds = (fd_set *)malloc(fdsetsize); if (!rfds) { log_err("malloc(%lu) failed", (unsigned long)fdsetsize); return -1; } wfds = (fd_set *)malloc(fdsetsize); if (!wfds) { log_err("malloc(%lu) failed", (unsigned long)fdsetsize); free(rfds); return -1; } control_setrun(); signal(SIGINT, sasyncd_stop); signal(SIGTERM, sasyncd_stop); timer_add("carp_undemote", CARP_DEMOTE_MAXTIME, monitor_carpundemote, NULL); while (!daemon_shutdown) { memset(rfds, 0, fdsetsize); memset(wfds, 0, fdsetsize); maxfd = net_set_rfds(rfds); n = net_set_pending_wfds(wfds); if (n > maxfd) maxfd = n; pfkey_set_rfd(rfds); pfkey_set_pending_wfd(wfds); if (cfgstate.pfkey_socket + 1 > maxfd) maxfd = cfgstate.pfkey_socket + 1; carp_set_rfd(rfds); if (cfgstate.route_socket + 1 > maxfd) maxfd = cfgstate.route_socket + 1; timeout = &tv; timer_next_event(&tv); n = select(maxfd, rfds, wfds, 0, timeout); if (n == -1) { if (errno != EINTR) { log_err("select()"); sleep(1); } } else if (n) { net_handle_messages(rfds); net_send_messages(wfds); pfkey_read_message(rfds); pfkey_send_message(wfds); carp_read_message(rfds); } timer_run(); /* Mostly for debugging. */ if (getppid() != ppid) { log_msg(0, "sasyncd: parent died"); daemon_shutdown++; } } free(rfds); free(wfds); return 0; }
/** Initialize the IPcheck subsystem. */ void IPcheck_init(void) { timer_add(timer_init(&expireTimer), ip_registry_expire, 0, TT_PERIODIC, 60); }
int main(int argc, char **argv) { struct timeval tv; struct timer *t; time_t now = time(NULL); long interval; /* * Set timers for every second from 1s ago to 10s in the future. * The -1s and +0s ones should fire immediately (due to the use of * time() for setting, the +0s one will be some large fraction of * a second late), and the rest should fire with relatively low * error. */ timer_add(now + 10, t1, NULL); timer_add(now + 7, t1, NULL); timer_add(now + 3, t1, NULL); timer_add(now + 1, t1, NULL); timer_add(now - 1, t1, NULL); timer_add(now + 6, t1, NULL); timer_add(now + 5, t1, NULL); timer_add(now + 0, t1, NULL); timer_add(now + 4, t1, NULL); timer_add(now + 2, t1, NULL); timer_add(now + 8, t1, NULL); timer_add(now + 9, t1, NULL); /* Add then remove an extra timer at +4s. */ t = timer_add(now + 4, t1, NULL); timer_delete(t); for (;;) { timer_next(&tv, NULL); assert(timer_count < 13); /* We only set 12 timers; if 13 go off, we lose. */ fprintf(stderr, "Interval: %ld.%06ld\n", (long int)tv.tv_sec, (long int)tv.tv_usec); interval = (long)tv.tv_sec * 1000000 + (long)tv.tv_usec; if (timer_count == 12) { /* After last timer, make sure we get the 1-hour delay. */ assert(tv.tv_sec == 3600); break; } /* If this assertion fails, it's because a timer got dropped. */ assert(tv.tv_sec < 3600); if (timer_count > 2) { /* First two are special. */ /* If this assertion fails, we're screwing up the scheduling. */ assert(interval > 500000); /* If this assertion fails, it took a *long* time to process a timer. */ assert(interval > 999000); } /* If this assertion fails, we're screwing up the scheduling. */ assert(interval < 1000000); select(0, NULL, NULL, NULL, &tv); } return (0); }
int main(void) { u8 i1; sysclk_init(); init_dbg_rs232(FMCK_HZ); init_gpio(); assign_main_event_handlers(); init_events(); init_tc(); init_spi(); init_adc(); irq_initialize_vectors(); register_interrupts(); cpu_irq_enable(); init_usb_host(); init_monome(); print_dbg("\r\n\n// meadowphysics //////////////////////////////// "); print_dbg_ulong(sizeof(flashy)); print_dbg(" "); print_dbg_ulong(sizeof(m)); if(flash_is_fresh()) { print_dbg("\r\nfirst run."); flash_unfresh(); flashc_memset32((void*)&(flashy.preset_select), 0, 4, true); // clear out some reasonable defaults for(i1=0;i1<8;i1++) { m.positions[i1] = i1; m.points[i1] = i1; m.points_save[i1] = i1; m.triggers[i1] = 0; m.trig_dests[i1] = 0; m.rules[i1] = 0; m.rule_dests[i1] = i1; } m.positions[0] = m.points[0] = 3; m.trig_dests[0] = 254; // save all presets, clear glyphs for(i1=0;i1<8;i1++) { flashc_memcpy((void *)&flashy.m[i1], &m, sizeof(m), true); glyph[i1] = (1<<i1); flashc_memcpy((void *)&flashy.glyph[i1], &glyph, sizeof(glyph), true); } } else { // load from flash at startup preset_select = flashy.preset_select; flash_read(); for(i1=0;i1<8;i1++) glyph[i1] = flashy.glyph[preset_select][i1]; } LENGTH = 15; SIZE = 16; re = &refresh; clock_pulse = &clock; clock_external = !gpio_get_pin_value(B09); timer_add(&clockTimer,120,&clockTimer_callback, NULL); timer_add(&keyTimer,50,&keyTimer_callback, NULL); timer_add(&adcTimer,100,&adcTimer_callback, NULL); clock_temp = 10000; // out of ADC range to force tempo // setup daisy chain for two dacs // spi_selectChip(SPI,DAC_SPI); // spi_write(SPI,0x80); // spi_write(SPI,0xff); // spi_write(SPI,0xff); // spi_unselectChip(SPI,DAC_SPI); while (true) { check_events(); } }
int rls_mod_init(void) { load_tm_f load_tm; bind_dlg_mod_f bind_dlg; struct timer_ln *i_timer = NULL; DEBUG_LOG("RLS module initialization\n"); /* ??? if other module uses this libraries it might be a problem ??? */ xmlInitParser(); DEBUG_LOG(" ... common libraries\n"); qsa_initialize(); if (time_event_management_init() != 0) { LOG(L_ERR, "rls_mod_init(): Can't initialize time event management!\n"); return -1; } if (subscription_management_init() != 0) { LOG(L_ERR, "rls_mod_init(): Can't initialize time event management!\n"); return -1; } /* import the TM auto-loading function */ if ( !(load_tm=(load_tm_f)find_export("load_tm", NO_SCRIPT, 0))) { LOG(L_ERR, "rls_mod_init(): Can't import tm!\n"); return -1; } /* let the auto-loading function load all TM stuff */ if (load_tm(&tmb)==-1) { LOG(L_ERR, "rls_mod_init(): load_tm() failed\n"); return -1; } bind_dlg = (bind_dlg_mod_f)find_export("bind_dlg_mod", -1, 0); if (!bind_dlg) { LOG(L_ERR, "Can't import dlg\n"); return -1; } if (bind_dlg(&dlg_func) != 0) { return -1; } if (rls_init() != 0) { return -1; } if (vs_init() != 0) { return -1; } /* xcap_servers = (ptr_vector_t*)mem_alloc(sizeof(ptr_vector_t)); if (!xcap_servers) { LOG(L_ERR, "rls_mod_init(): can't allocate memory for XCAP servers vector\n"); return -1; } ptr_vector_init(xcap_servers, 8); */ /* set authorization type according to requested "auth type name" * and other (type specific) parameters */ if (set_auth_params(&rls_auth_params, auth_type_str) != 0) return -1; use_db = 0; if (db_mode > 0) { int db_url_len = db_url ? strlen(db_url) : 0; if (!db_url_len) { LOG(L_ERR, "rls_mod_init(): no db_url specified but db_mode > 0\n"); db_mode = 0; } } if (db_mode > 0) { if (bind_dbmod(db_url, &rls_dbf) < 0) { LOG(L_ERR, "rls_mod_init(): Can't bind database module via url %s\n", db_url); return -1; } if (!DB_CAPABILITY(rls_dbf, DB_CAP_ALL)) { /* ? */ LOG(L_ERR, "rls_mod_init(): Database module does not implement all functions needed by the module\n"); return -1; } use_db = 1; } /* once-shot timer for reloading data from DB - * needed because it can trigger database operations * in other modules and they mostly intialize their * database connection in child_init functions */ i_timer = timer_alloc(); if (!i_timer) { ERR("can't allocate memory for DB init timer\n"); return -1; } else { timer_init(i_timer, init_timer_cb, i_timer, 0); timer_add(i_timer, S_TO_TICKS(init_timer_delay)); } fill_xcap_params = (fill_xcap_params_func)find_export("fill_xcap_params", 0, -1); return 0; }
void refresh_timeout(struct state *state, struct timeout *t) { timer_del(&state->timers, &t->timer); timer_add(&state->timers, &t->timer, timeabs_add(time_now(), t->interval)); }
int main(void) { struct timers timers; struct timer t[64]; struct list_head expired; struct timeabs earliest; uint64_t i; struct timeabs epoch = { { 0, 0 } }; /* This is how many tests you plan to run */ plan_tests(488); timers_init(&timers, epoch); ok1(timers_check(&timers, NULL)); ok1(!timer_earliest(&timers, &earliest)); timer_add(&timers, &t[0], timeabs_from_nsec(1)); ok1(timers_check(&timers, NULL)); ok1(timer_earliest(&timers, &earliest)); ok1(timeabs_eq(earliest, grains_to_time(t[0].time))); timer_del(&timers, &t[0]); ok1(timers_check(&timers, NULL)); ok1(!timer_earliest(&timers, &earliest)); /* Check timer ordering. */ for (i = 0; i < 32; i++) { timer_add(&timers, &t[i*2], timeabs_from_nsec(1ULL << i)); ok1(timers_check(&timers, NULL)); timer_add(&timers, &t[i*2+1], timeabs_from_nsec((1ULL << i) + 1)); ok1(timers_check(&timers, NULL)); } for (i = 0; i < 32; i++) { const struct timer *t1, *t2; t1 = get_first(&timers); ok1(t1 == &t[i*2] || t1 == &t[i*2+1]); timer_del(&timers, (struct timer *)t1); ok1(timers_check(&timers, NULL)); t2 = get_first(&timers); ok1(t2 != t1 && (t2 == &t[i*2] || t2 == &t[i*2+1])); timer_del(&timers, (struct timer *)t2); ok1(timers_check(&timers, NULL)); } /* Check expiry. */ for (i = 0; i < 32; i++) { uint64_t exp = (uint64_t)TIMER_GRANULARITY << i; timer_add(&timers, &t[i*2], timeabs_from_nsec(exp)); ok1(timers_check(&timers, NULL)); timer_add(&timers, &t[i*2+1], timeabs_from_nsec(exp + 1)); ok1(timers_check(&timers, NULL)); } for (i = 0; i < 32; i++) { struct timer *t1, *t2; ok1(timer_earliest(&timers, &earliest)); timers_expire(&timers, earliest, &expired); t1 = list_pop(&expired, struct timer, list); ok1(t1); t2 = list_pop(&expired, struct timer, list); ok1(t2); ok1(list_empty(&expired)); ok1(t1 == &t[i*2] || t1 == &t[i*2+1]); ok1(t2 != t1 && (t2 == &t[i*2] || t2 == &t[i*2+1])); ok1(timers_check(&timers, NULL)); } ok1(!timer_earliest(&timers, &earliest)); timers_cleanup(&timers); /* This exits depending on whether all tests passed */ return exit_status(); }
static void engine_loop(struct Generators *gen) { struct epoll_event *events; struct Socket *sock; size_t codesize; int events_count, i, wait, nevs, errcode; if ((events_count = feature_int(FEAT_POLLS_PER_LOOP)) < 20) events_count = 20; events = MyMalloc(sizeof(events[0]) * events_count); while (running) { if ((i = feature_int(FEAT_POLLS_PER_LOOP)) >= 20 && i != events_count) { events = MyRealloc(events, sizeof(events[0]) * i); events_count = i; } wait = timer_next(gen) ? (timer_next(gen) - CurrentTime) * 1000 : -1; Debug((DEBUG_INFO, "epoll: delay: %d (%d) %d", timer_next(gen), CurrentTime, wait)); nevs = epoll_wait(epoll_fd, events, events_count, wait); CurrentTime = time(0); if (nevs < 0) { if (errno != EINTR) { log_write(LS_SOCKET, L_ERROR, 0, "epoll() error: %m"); if (!errors++) timer_add(timer_init(&clear_error), error_clear, 0, TT_PERIODIC, ERROR_EXPIRE_TIME); else if (errors > EPOLL_ERROR_THRESHOLD) server_restart("too many epoll errors"); } continue; } for (i = 0; i < nevs; i++) { if (!(sock = events[i].data.ptr)) continue; gen_ref_inc(sock); Debug((DEBUG_ENGINE, "epoll: Checking socket %p (fd %d) state %s, events %s", sock, s_fd(sock), state_to_name(s_state(sock)), sock_flags(s_events(sock)))); if (events[i].events & EPOLLERR) { errcode = 0; codesize = sizeof(errcode); if (getsockopt(s_fd(sock), SOL_SOCKET, SO_ERROR, &errcode, &codesize) < 0) errcode = errno; if (errcode) { event_generate(ET_ERROR, sock, errcode); gen_ref_dec(sock); continue; } } switch (s_state(sock)) { case SS_CONNECTING: if (events[i].events & EPOLLOUT) /* connection completed */ event_generate(ET_CONNECT, sock, 0); break; case SS_LISTENING: if (events[i].events & EPOLLIN) /* incoming connection */ event_generate(ET_ACCEPT, sock, 0); break; case SS_NOTSOCK: case SS_CONNECTED: if (events[i].events & EPOLLIN) event_generate((events[i].events & EPOLLHUP) ? ET_EOF : ET_READ, sock, 0); if (events[i].events & EPOLLOUT) event_generate(ET_WRITE, sock, 0); break; case SS_DATAGRAM: case SS_CONNECTDG: if (events[i].events & EPOLLIN) event_generate(ET_READ, sock, 0); if (events[i].events & EPOLLOUT) event_generate(ET_WRITE, sock, 0); break; } gen_ref_dec(sock); } timer_run(); } }
int ikev2_pld_notify(struct iked *env, struct ikev2_payload *pld, struct iked_message *msg, size_t offset, size_t left) { struct ikev2_notify n; u_int8_t *buf, md[SHA_DIGEST_LENGTH]; size_t len; u_int32_t spi32; u_int64_t spi64; struct iked_spi *rekey; u_int16_t type; u_int16_t group; u_int16_t cpi; u_int8_t transform; if (ikev2_validate_notify(msg, offset, left, pld, &n)) return (-1); type = betoh16(n.n_type); log_debug("%s: protoid %s spisize %d type %s", __func__, print_map(n.n_protoid, ikev2_saproto_map), n.n_spisize, print_map(type, ikev2_n_map)); len = betoh16(pld->pld_length) - sizeof(*pld) - sizeof(n); if ((buf = ibuf_seek(msg->msg_data, offset + sizeof(n), len)) == NULL) return (-1); print_hex(buf, 0, len); if (!ikev2_msg_frompeer(msg)) return (0); switch (type) { case IKEV2_N_NAT_DETECTION_SOURCE_IP: case IKEV2_N_NAT_DETECTION_DESTINATION_IP: if (len != sizeof(md)) { log_debug("%s: malformed payload: hash size mismatch" " (%zu != %zu)", __func__, len, sizeof(md)); return (-1); } if (ikev2_nat_detection(env, msg, md, sizeof(md), type) == -1) return (-1); if (memcmp(buf, md, len) != 0) { log_debug("%s: %s detected NAT, enabling " "UDP encapsulation", __func__, print_map(type, ikev2_n_map)); /* * Enable UDP encapsulation of ESP packages if * the check detected NAT. */ if (msg->msg_sa != NULL) msg->msg_sa->sa_udpencap = 1; } print_hex(md, 0, sizeof(md)); break; case IKEV2_N_INVALID_KE_PAYLOAD: if (len != sizeof(group)) { log_debug("%s: malformed payload: group size mismatch" " (%zu != %zu)", __func__, len, sizeof(group)); return (-1); } if (!msg->msg_sa->sa_hdr.sh_initiator) { log_debug("%s: not an initiator", __func__); sa_free(env, msg->msg_sa); msg->msg_sa = NULL; return (-1); } memcpy(&group, buf, len); group = betoh16(group); if ((msg->msg_policy->pol_peerdh = group_get(group)) == NULL) { log_debug("%s: unable to select DH group %d", __func__, group); return (-1); } log_debug("%s: responder selected DH group %d", __func__, group); sa_free(env, msg->msg_sa); msg->msg_sa = NULL; timer_set(env, &env->sc_inittmr, ikev2_init_ike_sa, NULL); timer_add(env, &env->sc_inittmr, IKED_INITIATOR_INITIAL); break; case IKEV2_N_NO_ADDITIONAL_SAS: /* This makes sense for Child SAs only atm */ if (msg->msg_sa->sa_stateflags & IKED_REQ_CHILDSA) { ikev2_disable_rekeying(env, msg->msg_sa); msg->msg_sa->sa_stateflags &= ~IKED_REQ_CHILDSA; } break; case IKEV2_N_REKEY_SA: if (len != n.n_spisize) { log_debug("%s: malformed notification", __func__); return (-1); } rekey = &msg->msg_parent->msg_rekey; if (rekey->spi != 0) { log_debug("%s: rekeying of multiple SAs not supported", __func__); return (-1); } switch (n.n_spisize) { case 4: memcpy(&spi32, buf, len); rekey->spi = betoh32(spi32); break; case 8: memcpy(&spi64, buf, len); rekey->spi = betoh64(spi64); break; default: log_debug("%s: invalid spi size %d", __func__, n.n_spisize); return (-1); } rekey->spi_size = n.n_spisize; rekey->spi_protoid = n.n_protoid; log_debug("%s: rekey %s spi %s", __func__, print_map(n.n_protoid, ikev2_saproto_map), print_spi(rekey->spi, n.n_spisize)); break; case IKEV2_N_IPCOMP_SUPPORTED: if (len < sizeof(cpi) + sizeof(transform)) { log_debug("%s: ignoring malformed ipcomp notification", __func__); return (0); } memcpy(&cpi, buf, sizeof(cpi)); memcpy(&transform, buf + sizeof(cpi), sizeof(transform)); log_debug("%s: cpi 0x%x, transform %s, len %zu", __func__, betoh16(cpi), print_map(transform, ikev2_ipcomp_map), len); /* we only support deflate */ if ((msg->msg_policy->pol_flags & IKED_POLICY_IPCOMP) && (transform == IKEV2_IPCOMP_DEFLATE)) { msg->msg_sa->sa_ipcomp = transform; msg->msg_sa->sa_cpi_out = betoh16(cpi); } break; } return (0); }
void disc_reset() { curdrive = 0; disc_period = 32; timer_add(disc_poll, &disc_poll_time, &motoron, NULL); }
/** Read a 'packet' of data from a connection and process it. Read in * 8k chunks to give a better performance rating (for server * connections). Do some tricky stuff for client connections to make * sure they don't do any flooding >:-) -avalon * @param cptr Client from which to read data. * @param socket_ready If non-zero, more data can be read from the client's socket. * @return Positive number on success, zero on connection-fatal failure, negative * if user is killed. */ static int read_packet(struct Client *cptr, int socket_ready) { unsigned int dolen = 0; unsigned int length = 0; if (socket_ready && !(IsUser(cptr) && DBufLength(&(cli_recvQ(cptr))) > feature_uint(FEAT_CLIENT_FLOOD))) { #if defined(USE_SSL) switch (client_recv(cptr, readbuf, sizeof(readbuf), &length)) { #else switch (os_recv_nonb(cli_fd(cptr), readbuf, sizeof(readbuf), &length)) { #endif case IO_SUCCESS: if (length) { cli_lasttime(cptr) = CurrentTime; ClearPingSent(cptr); ClrFlag(cptr, FLAG_NONL); if (cli_lasttime(cptr) > cli_since(cptr)) cli_since(cptr) = cli_lasttime(cptr); } break; case IO_BLOCKED: break; case IO_FAILURE: cli_error(cptr) = errno; /* SetFlag(cptr, FLAG_DEADSOCKET); */ return 0; } } /* * For server connections, we process as many as we can without * worrying about the time of day or anything :) */ if (length > 0 && IsServer(cptr)) return server_dopacket(cptr, readbuf, length); else if (length > 0 && (IsHandshake(cptr) || IsConnecting(cptr))) return connect_dopacket(cptr, readbuf, length); else { /* * Before we even think of parsing what we just read, stick * it on the end of the receive queue and do it when its * turn comes around. */ if (length > 0 && dbuf_put(cptr, &(cli_recvQ(cptr)), readbuf, length) == 0) return exit_client(cptr, cptr, &me, "dbuf_put fail"); if ((DBufLength(&(cli_recvQ(cptr))) > feature_uint(FEAT_CLIENT_FLOOD)) && !IsChannelService(cptr)) return exit_client(cptr, cptr, &me, "Excess Flood"); while (DBufLength(&(cli_recvQ(cptr))) && !NoNewLine(cptr) && (IsTrusted(cptr) || IsChannelService(cptr) || cli_since(cptr) - CurrentTime < 10)) { dolen = dbuf_getmsg(&(cli_recvQ(cptr)), cli_buffer(cptr), BUFSIZE); /* * Devious looking...whats it do ? well..if a client * sends a *long* message without any CR or LF, then * dbuf_getmsg fails and we pull it out using this * loop which just gets the next 512 bytes and then * deletes the rest of the buffer contents. * -avalon */ if (dolen == 0) { if (DBufLength(&(cli_recvQ(cptr))) < 510) SetFlag(cptr, FLAG_NONL); else { /* More than 512 bytes in the line - drop the input and yell * at the client. */ DBufClear(&(cli_recvQ(cptr))); send_reply(cptr, ERR_INPUTTOOLONG); } } else if (client_dopacket(cptr, dolen) == CPTR_KILLED) return CPTR_KILLED; /* * If it has become registered as a Server * then skip the per-message parsing below. */ if (IsHandshake(cptr) || IsServer(cptr)) { while (-1) { dolen = dbuf_get(&(cli_recvQ(cptr)), readbuf, sizeof(readbuf)); if (dolen <= 0) return 1; else if (dolen == 0) { if (DBufLength(&(cli_recvQ(cptr))) < 510) SetFlag(cptr, FLAG_NONL); else { DBufClear(&(cli_recvQ(cptr))); /* send_reply(cptr, ERR_INPUTTOOLONG); */ } } else if ((IsServer(cptr) && server_dopacket(cptr, readbuf, dolen) == CPTR_KILLED) || (!IsServer(cptr) && connect_dopacket(cptr, readbuf, dolen) == CPTR_KILLED)) return CPTR_KILLED; } } } /* If there's still data to process, wait 2 seconds first */ if (DBufLength(&(cli_recvQ(cptr))) && !NoNewLine(cptr) && !t_onqueue(&(cli_proc(cptr)))) { Debug((DEBUG_LIST, "Adding client process timer for %C", cptr)); cli_freeflag(cptr) |= FREEFLAG_TIMER; timer_add(&(cli_proc(cptr)), client_timer_callback, cli_connect(cptr), TT_RELATIVE, 2); } } return 1; } /** Start a connection to another server. * @param aconf Connect block data for target server. * @param by Client who requested the connection (if any). * @return Non-zero on success; zero on failure. */ int connect_server(struct ConfItem* aconf, struct Client* by) { struct Client* cptr = 0; assert(0 != aconf); if (aconf->dns_pending) { sendto_opmask(0, SNO_OLDSNO, "Server %s connect DNS pending", aconf->name); return 0; } Debug((DEBUG_NOTICE, "Connect to %s[@%s]", aconf->name, ircd_ntoa(&aconf->address.addr))); if ((cptr = FindClient(aconf->name))) { if (IsServer(cptr) || IsMe(cptr)) { sendto_opmask(0, SNO_OLDSNO, "Server %s already present from %s", aconf->name, cli_name(cli_from(cptr))); if (by && IsUser(by) && !MyUser(by)) { sendcmdto_one(&me, CMD_NOTICE, by, "%C :Server %s already present " "from %s", by, aconf->name, cli_name(cli_from(cptr))); } return 0; } else if (IsHandshake(cptr) || IsConnecting(cptr)) { if (by && IsUser(by)) { sendcmdto_one(&me, CMD_NOTICE, by, "%C :Connection to %s already in " "progress", by, cli_name(cptr)); } return 0; } } /* * If we don't know the IP# for this host and it is a hostname and * not a ip# string, then try and find the appropriate host record. */ if (!irc_in_addr_valid(&aconf->address.addr) && !ircd_aton(&aconf->address.addr, aconf->host)) { char buf[HOSTLEN + 1]; host_from_uh(buf, aconf->host, HOSTLEN); gethost_byname(buf, connect_dns_callback, aconf); aconf->dns_pending = 1; return 0; } cptr = make_client(NULL, STAT_UNKNOWN_SERVER); /* * Copy these in so we have something for error detection. */ ircd_strncpy(cli_name(cptr), aconf->name, HOSTLEN); ircd_strncpy(cli_sockhost(cptr), aconf->host, HOSTLEN); /* * Attach config entries to client here rather than in * completed_connection. This to avoid null pointer references */ attach_confs_byhost(cptr, aconf->host, CONF_SERVER); if (!find_conf_byhost(cli_confs(cptr), aconf->host, CONF_SERVER)) { sendto_opmask(0, SNO_OLDSNO, "Host %s is not enabled for " "connecting: no Connect block", aconf->name); if (by && IsUser(by) && !MyUser(by)) { sendcmdto_one(&me, CMD_NOTICE, by, "%C :Connect to host %s failed: no " "Connect block", by, aconf->name); } det_confs_butmask(cptr, 0); free_client(cptr); return 0; } /* * attempt to connect to the server in the conf line */ if (!connect_inet(aconf, cptr)) { if (by && IsUser(by) && !MyUser(by)) { sendcmdto_one(&me, CMD_NOTICE, by, "%C :Couldn't connect to %s", by, cli_name(cptr)); } det_confs_butmask(cptr, 0); free_client(cptr); return 0; } /* * NOTE: if we're here we have a valid C:Line and the client should * have started the connection and stored the remote address/port and * ip address name in itself * * The socket has been connected or connect is in progress. */ make_server(cptr); if (by && IsUser(by)) { ircd_snprintf(0, cli_serv(cptr)->by, sizeof(cli_serv(cptr)->by), "%s%s", NumNick(by)); assert(0 == cli_serv(cptr)->user); cli_serv(cptr)->user = cli_user(by); cli_user(by)->refcnt++; } else { *(cli_serv(cptr))->by = '\0'; /* strcpy(cptr->serv->by, "Auto"); */ } cli_serv(cptr)->up = &me; SetConnecting(cptr); if (cli_fd(cptr) > HighestFd) HighestFd = cli_fd(cptr); LocalClientArray[cli_fd(cptr)] = cptr; Count_newunknown(UserStats); /* Actually we lie, the connect hasn't succeeded yet, but we have a valid * cptr, so we register it now. * Maybe these two calls should be merged. */ add_client_to_list(cptr); hAddClient(cptr); /* nextping = CurrentTime; */ return (s_state(&cli_socket(cptr)) == SS_CONNECTED) ? completed_connection(cptr) : 1; } /** Find the real hostname for the host running the server (or one which * matches the server's name) and its primary IP#. Hostname is stored * in the client structure passed as a pointer. */ void init_server_identity(void) { const struct LocalConf* conf = conf_get_local(); assert(0 != conf); ircd_strncpy(cli_name(&me), conf->name, HOSTLEN); SetYXXServerName(&me, conf->numeric); } /** Process events on a client socket. * @param ev Socket event structure that has a struct Connection as * its associated data. */ static void client_sock_callback(struct Event* ev) { struct Client* cptr; struct Connection* con; char *fmt = "%s"; char *fallback = 0; assert(0 != ev_socket(ev)); assert(0 != s_data(ev_socket(ev))); con = (struct Connection*) s_data(ev_socket(ev)); assert(0 != con_client(con) || ev_type(ev) == ET_DESTROY); cptr = con_client(con); assert(0 == cptr || con == cli_connect(cptr)); switch (ev_type(ev)) { case ET_DESTROY: con_freeflag(con) &= ~FREEFLAG_SOCKET; if (!con_freeflag(con) && !cptr) free_connection(con); #if defined(USE_SSL) ssl_free(ev_socket(ev)); #endif break; case ET_CONNECT: /* socket connection completed */ if (!completed_connection(cptr) || IsDead(cptr)) fallback = cli_info(cptr); break; case ET_ERROR: /* an error occurred */ fallback = cli_info(cptr); cli_error(cptr) = ev_data(ev); /* If the OS told us we have a bad file descriptor, we should * record that for future reference. */ if (cli_error(cptr) == EBADF) cli_fd(cptr) = -1; if (s_state(&(con_socket(con))) == SS_CONNECTING) { completed_connection(cptr); /* for some reason, the os_get_sockerr() in completed_connection() * can return 0 even when ev_data(ev) indicates a real error, so * re-assign the client error here. */ cli_error(cptr) = ev_data(ev); break; } /*FALLTHROUGH*/ case ET_EOF: /* end of file on socket */ Debug((DEBUG_ERROR, "READ ERROR: fd = %d %d", cli_fd(cptr), cli_error(cptr))); SetFlag(cptr, FLAG_DEADSOCKET); if ((IsServer(cptr) || IsHandshake(cptr)) && cli_error(cptr) == 0) { exit_client_msg(cptr, cptr, &me, "Server %s closed the connection (%s)", cli_name(cptr), cli_serv(cptr)->last_error_msg); return; } else { fmt = "Read error: %s"; fallback = "EOF from client"; } break; case ET_WRITE: /* socket is writable */ ClrFlag(cptr, FLAG_BLOCKED); if (cli_listing(cptr) && MsgQLength(&(cli_sendQ(cptr))) < 2048) list_next_channels(cptr); Debug((DEBUG_SEND, "Sending queued data to %C", cptr)); send_queued(cptr); break; case ET_READ: /* socket is readable */ if (!IsDead(cptr)) { Debug((DEBUG_DEBUG, "Reading data from %C", cptr)); if (read_packet(cptr, 1) == 0) /* error while reading packet */ fallback = "EOF from client"; } break; default: assert(0 && "Unrecognized socket event in client_sock_callback()"); break; } assert(0 == cptr || 0 == cli_connect(cptr) || con == cli_connect(cptr)); if (fallback) { const char* msg = (cli_error(cptr)) ? strerror(cli_error(cptr)) : fallback; if (!msg) msg = "Unknown error"; exit_client_msg(cptr, cptr, &me, fmt, msg); } } /** Process a timer on client socket. * @param ev Timer event that has a struct Connection as its * associated data. */ static void client_timer_callback(struct Event* ev) { struct Client* cptr; struct Connection* con; assert(0 != ev_timer(ev)); assert(0 != t_data(ev_timer(ev))); assert(ET_DESTROY == ev_type(ev) || ET_EXPIRE == ev_type(ev)); con = (struct Connection*) t_data(ev_timer(ev)); assert(0 != con_client(con) || ev_type(ev) == ET_DESTROY); cptr = con_client(con); assert(0 == cptr || con == cli_connect(cptr)); if (ev_type(ev)== ET_DESTROY) { con_freeflag(con) &= ~FREEFLAG_TIMER; /* timer has expired... */ if (!con_freeflag(con) && !cptr) free_connection(con); /* client is being destroyed */ } else { Debug((DEBUG_LIST, "Client process timer for %C expired; processing", cptr)); read_packet(cptr, 0); /* read_packet will re-add timer if needed */ } assert(0 == cptr || 0 == cli_connect(cptr) || con == cli_connect(cptr)); }
// monome: start polling void timers_set_monome(void) { // print_dbg("\r\n setting monome timers"); timer_add(&monomePollTimer, 20, &monome_poll_timer_callback, NULL ); timer_add(&monomeRefreshTimer, 30, &monome_refresh_timer_callback, NULL ); }
// monome: start polling void timers_set_monome(void) { timer_add(&monomePollTimer, 20, &monome_poll_timer_callback, NULL ); timer_add(&monomeRefreshTimer, 30, &monome_refresh_timer_callback, NULL ); }
int init_dst_blacklist() { int ret; #ifdef BLST_LOCK_PER_BUCKET int r; #endif if (dst_blacklist_init==0) { /* the dst blacklist is turned off */ default_core_cfg.use_dst_blacklist=0; return 0; } ret=-1; #ifdef DST_BLACKLIST_HOOKS if (init_blacklist_hooks()!=0){ ret=E_OUT_OF_MEM; goto error; } #endif blst_mem_used=shm_malloc(sizeof(*blst_mem_used)); if (blst_mem_used==0){ ret=E_OUT_OF_MEM; goto error; } *blst_mem_used=0; dst_blst_hash=shm_malloc(sizeof(struct dst_blst_lst_head) * DST_BLST_HASH_SIZE); if (dst_blst_hash==0){ ret=E_OUT_OF_MEM; goto error; } memset(dst_blst_hash, 0, sizeof(struct dst_blst_lst_head) * DST_BLST_HASH_SIZE); #ifdef BLST_LOCK_PER_BUCKET for (r=0; r<DST_BLST_HASH_SIZE; r++){ if (lock_init(&dst_blst_hash[r].lock)==0){ ret=-1; goto error; } } #elif defined BLST_LOCK_SET blst_lock_set=lock_set_alloc(DST_BLST_HASH_SIZE); if (blst_lock_set==0){ ret=E_OUT_OF_MEM; goto error; } if (lock_set_init(blst_lock_set)==0){ lock_set_dealloc(blst_lock_set); blst_lock_set=0; ret=-1; goto error; } #else /* BLST_ONE_LOCK */ blst_lock=lock_alloc(); if (blst_lock==0){ ret=E_OUT_OF_MEM; goto error; } if (lock_init(blst_lock)==0){ lock_dealloc(blst_lock); blst_lock=0; ret=-1; goto error; } #endif /* BLST*LOCK*/ blst_timer_h=timer_alloc(); if (blst_timer_h==0){ ret=E_OUT_OF_MEM; goto error; } /* fix options */ default_core_cfg.blst_max_mem<<=10; /* in Kb */ /* TODO: test with 0 */ if (blst_timer_interval){ timer_init(blst_timer_h, blst_timer, 0 ,0); /* slow timer */ if (timer_add(blst_timer_h, S_TO_TICKS(blst_timer_interval))<0){ LOG(L_CRIT, "BUG: init_dst_blacklist: failed to add the timer\n"); timer_free(blst_timer_h); blst_timer_h=0; goto error; } } return 0; error: destroy_dst_blacklist(); return ret; }
/** Look for any connections that we should try to initiate. * Reschedules itself to run again at the appropriate time. * @param[in] ev Timer event (ignored). */ static void try_connections(struct Event* ev) { struct ConfItem* aconf; struct ConfItem** pconf; time_t next; struct Jupe* ajupe; int hold; int done; assert(ET_EXPIRE == ev_type(ev)); assert(0 != ev_timer(ev)); Debug((DEBUG_NOTICE, "Connection check at : %s", myctime(CurrentTime))); next = CurrentTime + feature_int(FEAT_CONNECTFREQUENCY); done = 0; for (aconf = GlobalConfList; aconf; aconf = aconf->next) { /* Only consider server items with non-zero port and non-zero * connect times that are not actively juped. */ if (!(aconf->status & CONF_SERVER) || aconf->address.port == 0 || !(aconf->flags & CONF_AUTOCONNECT) || ((ajupe = jupe_find(aconf->name)) && JupeIsActive(ajupe))) continue; /* Do we need to postpone this connection further? */ hold = aconf->hold > CurrentTime; /* Update next possible connection check time. */ if (hold && next > aconf->hold) next = aconf->hold; /* Do not try to connect if its use is still on hold until future, * we have already initiated a connection this try_connections(), * too many links in its connection class, it is already linked, * or if connect rules forbid a link now. */ if (hold || done || (ConfLinks(aconf) > ConfMaxLinks(aconf)) || FindServer(aconf->name) || conf_eval_crule(aconf->name, CRULE_MASK)) continue; /* Ensure it is at the end of the list for future checks. */ if (aconf->next) { /* Find aconf's location in the list and splice it out. */ for (pconf = &GlobalConfList; *pconf; pconf = &(*pconf)->next) if (*pconf == aconf) *pconf = aconf->next; /* Reinsert it at the end of the list (where pconf is now). */ *pconf = aconf; aconf->next = 0; } /* Activate the connection itself. */ if (connect_server(aconf, 0)) sendto_opmask_butone(0, SNO_OLDSNO, "Connection to %s activated.", aconf->name); /* And stop looking for further candidates. */ done = 1; } Debug((DEBUG_NOTICE, "Next connection check : %s", myctime(next))); timer_add(&connect_timer, try_connections, 0, TT_ABSOLUTE, next); }
static void fluidsynth_file_decode(struct decoder *decoder, const char *path_fs) { static const struct audio_format audio_format = { .sample_rate = 48000, .format = SAMPLE_FORMAT_S16, .channels = 2, }; char setting_sample_rate[] = "synth.sample-rate"; /* char setting_verbose[] = "synth.verbose"; char setting_yes[] = "yes"; */ const char *soundfont_path; fluid_settings_t *settings; fluid_synth_t *synth; fluid_player_t *player; char *path_dup; int ret; struct timer *timer; enum decoder_command cmd; soundfont_path = config_get_string("soundfont", "/usr/share/sounds/sf2/FluidR3_GM.sf2"); /* set up fluid settings */ settings = new_fluid_settings(); if (settings == NULL) return; fluid_settings_setnum(settings, setting_sample_rate, 48000); /* fluid_settings_setstr(settings, setting_verbose, setting_yes); */ /* create the fluid synth */ synth = new_fluid_synth(settings); if (synth == NULL) { delete_fluid_settings(settings); return; } ret = fluid_synth_sfload(synth, soundfont_path, true); if (ret < 0) { g_warning("fluid_synth_sfload() failed"); delete_fluid_synth(synth); delete_fluid_settings(settings); return; } /* create the fluid player */ player = new_fluid_player(synth); if (player == NULL) { delete_fluid_synth(synth); delete_fluid_settings(settings); return; } /* temporarily duplicate the path_fs string, because fluidsynth wants a writable string */ path_dup = g_strdup(path_fs); ret = fluid_player_add(player, path_dup); g_free(path_dup); if (ret != 0) { g_warning("fluid_player_add() failed"); delete_fluid_player(player); delete_fluid_synth(synth); delete_fluid_settings(settings); return; } /* start the player */ ret = fluid_player_play(player); if (ret != 0) { g_warning("fluid_player_play() failed"); delete_fluid_player(player); delete_fluid_synth(synth); delete_fluid_settings(settings); return; } /* set up a timer for synchronization; fluidsynth always decodes in real time, which forces us to synchronize */ /* XXX is there any way to switch off real-time decoding? */ timer = timer_new(&audio_format); timer_start(timer); /* initialization complete - announce the audio format to the MPD core */ decoder_initialized(decoder, &audio_format, false, -1); do { int16_t buffer[2048]; const unsigned max_frames = G_N_ELEMENTS(buffer) / 2; /* synchronize with the fluid player */ timer_add(timer, sizeof(buffer)); timer_sync(timer); /* read samples from fluidsynth and send them to the MPD core */ ret = fluid_synth_write_s16(synth, max_frames, buffer, 0, 2, buffer, 1, 2); /* XXX how do we see whether the player is done? We can't access the private attribute player->status */ if (ret != 0) break; cmd = decoder_data(decoder, NULL, buffer, sizeof(buffer), 0); } while (cmd == DECODE_COMMAND_NONE); /* clean up */ timer_free(timer); fluid_player_stop(player); fluid_player_join(player); delete_fluid_player(player); delete_fluid_synth(synth); delete_fluid_settings(settings); } static struct tag * fluidsynth_tag_dup(const char *file) { struct tag *tag = tag_new(); /* to be implemented */ (void)file; return tag; } static const char *const fluidsynth_suffixes[] = { "mid", NULL }; const struct decoder_plugin fluidsynth_decoder_plugin = { .name = "fluidsynth", .init = fluidsynth_init, .file_decode = fluidsynth_file_decode, .tag_dup = fluidsynth_tag_dup, .suffixes = fluidsynth_suffixes, };
/** Check for clients that have not sent a ping response recently. * Reschedules itself to run again at the appropriate time. * @param[in] ev Timer event (ignored). */ static void check_pings(struct Event* ev) { int expire = 0; int next_check = CurrentTime; int max_ping = 0; int i; assert(ET_EXPIRE == ev_type(ev)); assert(0 != ev_timer(ev)); next_check += feature_int(FEAT_PINGFREQUENCY); /* Scan through the client table */ for (i=0; i <= HighestFd; i++) { struct Client *cptr = LocalClientArray[i]; if (!cptr) continue; assert(&me != cptr); /* I should never be in the local client array! */ /* Remove dead clients. */ if (IsDead(cptr)) { exit_client(cptr, cptr, &me, cli_info(cptr)); continue; } max_ping = IsRegistered(cptr) ? client_get_ping(cptr) : feature_int(FEAT_CONNECTTIMEOUT); Debug((DEBUG_DEBUG, "check_pings(%s)=status:%s limit: %d current: %d", cli_name(cptr), IsPingSent(cptr) ? "[Ping Sent]" : "[]", max_ping, (int)(CurrentTime - cli_lasttime(cptr)))); /* If it's a server and we have not sent an AsLL lately, do so. */ if (IsServer(cptr)) { if (CurrentTime - cli_serv(cptr)->asll_last >= max_ping) { char *asll_ts; SetPingSent(cptr); cli_serv(cptr)->asll_last = CurrentTime; expire = cli_serv(cptr)->asll_last + max_ping; asll_ts = militime_float(NULL); sendcmdto_prio_one(&me, CMD_PING, cptr, "!%s %s %s", asll_ts, cli_name(cptr), asll_ts); } expire = cli_serv(cptr)->asll_last + max_ping; if (expire < next_check) next_check = expire; } /* Ok, the thing that will happen most frequently, is that someone will * have sent something recently. Cover this first for speed. * -- * If it's an unregistered client and hasn't managed to register within * max_ping then it's obviously having problems (broken client) or it's * just up to no good, so we won't skip it, even if its been sending * data to us. * -- hikari */ if ((CurrentTime-cli_lasttime(cptr) < max_ping) && IsRegistered(cptr)) { expire = cli_lasttime(cptr) + max_ping; if (expire < next_check) next_check = expire; continue; } /* Unregistered clients pingout after max_ping seconds, they don't * get given a second chance - if they were then people could not quite * finish registration and hold resources without being subject to k/g * lines */ if (!IsRegistered(cptr)) { assert(!IsServer(cptr)); /* If client authorization time has expired, ask auth whether they * should be checked again later. */ if ((CurrentTime-cli_firsttime(cptr) >= max_ping) && auth_ping_timeout(cptr)) continue; /* OK, they still have enough time left, so we'll just skip to the * next client. Set the next check to be when their time is up, if * that's before the currently scheduled next check -- hikari */ expire = cli_firsttime(cptr) + max_ping; if (expire < next_check) next_check = expire; continue; } /* Quit the client after max_ping*2 - they should have answered by now */ if (CurrentTime-cli_lasttime(cptr) >= (max_ping*2) ) { /* If it was a server, then tell ops about it. */ if (IsServer(cptr) || IsConnecting(cptr) || IsHandshake(cptr)) sendto_opmask_butone(0, SNO_OLDSNO, "No response from %s, closing link", cli_name(cptr)); exit_client_msg(cptr, cptr, &me, "Ping timeout"); continue; } if (!IsPingSent(cptr)) { /* If we haven't PINGed the connection and we haven't heard from it in a * while, PING it to make sure it is still alive. */ SetPingSent(cptr); /* If we're late in noticing don't hold it against them :) */ cli_lasttime(cptr) = CurrentTime - max_ping; if (IsUser(cptr)) sendrawto_one(cptr, MSG_PING " :%s", cli_name(&me)); else sendcmdto_prio_one(&me, CMD_PING, cptr, ":%s", cli_name(&me)); } expire = cli_lasttime(cptr) + max_ping * 2; if (expire < next_check) next_check=expire; } assert(next_check >= CurrentTime); Debug((DEBUG_DEBUG, "[%i] check_pings() again in %is", CurrentTime, next_check-CurrentTime)); timer_add(&ping_timer, check_pings, 0, TT_ABSOLUTE, next_check); }
int ikev2_msg_send(struct iked *env, struct iked_message *msg) { struct iked_sa *sa = msg->msg_sa; struct ibuf *buf = msg->msg_data; uint32_t natt = 0x00000000; int isnatt = 0; uint8_t exchange, flags; struct ike_header *hdr; struct iked_message *m; if (buf == NULL || (hdr = ibuf_seek(msg->msg_data, msg->msg_offset, sizeof(*hdr))) == NULL) return (-1); isnatt = (msg->msg_natt || (msg->msg_sa && msg->msg_sa->sa_natt)); exchange = hdr->ike_exchange; flags = hdr->ike_flags; log_info("%s: %s %s from %s to %s msgid %u, %ld bytes%s", __func__, print_map(exchange, ikev2_exchange_map), (flags & IKEV2_FLAG_RESPONSE) ? "response" : "request", print_host((struct sockaddr *)&msg->msg_local, NULL, 0), print_host((struct sockaddr *)&msg->msg_peer, NULL, 0), betoh32(hdr->ike_msgid), ibuf_length(buf), isnatt ? ", NAT-T" : ""); if (isnatt) { if (ibuf_prepend(buf, &natt, sizeof(natt)) == -1) { log_debug("%s: failed to set NAT-T", __func__); return (-1); } msg->msg_offset += sizeof(natt); } if ((sendto(msg->msg_fd, ibuf_data(buf), ibuf_size(buf), 0, (struct sockaddr *)&msg->msg_peer, msg->msg_peerlen)) == -1) { log_warn("%s: sendto", __func__); return (-1); } if (!sa) return (0); if ((m = ikev2_msg_copy(env, msg)) == NULL) { log_debug("%s: failed to copy a message", __func__); return (-1); } m->msg_exchange = exchange; if (flags & IKEV2_FLAG_RESPONSE) { TAILQ_INSERT_TAIL(&sa->sa_responses, m, msg_entry); timer_set(env, &m->msg_timer, ikev2_msg_response_timeout, m); timer_add(env, &m->msg_timer, IKED_RESPONSE_TIMEOUT); } else { TAILQ_INSERT_TAIL(&sa->sa_requests, m, msg_entry); timer_set(env, &m->msg_timer, ikev2_msg_retransmit_timeout, m); timer_add(env, &m->msg_timer, IKED_RETRANSMIT_TIMEOUT); } return (0); }
/** Run the daemon. * @param[in] argc Number of arguments in \a argv. * @param[in] argv Arguments to program execution. */ int main(int argc, char **argv) { CurrentTime = time(NULL); thisServer.argc = argc; thisServer.argv = argv; thisServer.uid = getuid(); thisServer.euid = geteuid(); #ifdef MDEBUG mem_dbg_initialise(); #endif #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_CORE) set_core_limit(); #endif umask(077); /* better safe than sorry --SRB */ memset(&me, 0, sizeof(me)); memset(&me_con, 0, sizeof(me_con)); cli_connect(&me) = &me_con; cli_fd(&me) = -1; parse_command_line(argc, argv); if (chdir(dpath)) { fprintf(stderr, "Fail: Cannot chdir(%s): %s, check DPATH\n", dpath, strerror(errno)); return 2; } if (!set_userid_if_needed()) return 3; /* Check paths for accessibility */ if (!check_file_access(SPATH, 'S', X_OK) || !check_file_access(configfile, 'C', R_OK)) return 4; if (!init_connection_limits()) return 9; close_connections(!(thisServer.bootopt & (BOOT_DEBUG | BOOT_TTY | BOOT_CHKCONF))); /* daemon_init() must be before event_init() because kqueue() FDs * are, perversely, not inherited across fork(). */ daemon_init(thisServer.bootopt & BOOT_TTY); #ifdef DEBUGMODE /* Must reserve fd 2... */ if (debuglevel >= 0 && !(thisServer.bootopt & BOOT_TTY)) { int fd; if ((fd = open("/dev/null", O_WRONLY)) < 0) { fprintf(stderr, "Unable to open /dev/null (to reserve fd 2): %s\n", strerror(errno)); return 8; } if (fd != 2 && dup2(fd, 2) < 0) { fprintf(stderr, "Unable to reserve fd 2; dup2 said: %s\n", strerror(errno)); return 8; } } #endif event_init(MAXCONNECTIONS); setup_signals(); feature_init(); /* initialize features... */ log_init(*argv); set_nomem_handler(outofmemory); initload(); init_list(); init_hash(); init_class(); initwhowas(); initmsgtree(); initstats(); /* we need this for now, when we're modular this should be removed -- hikari */ ircd_crypt_init(); motd_init(); if (!init_conf()) { log_write(LS_SYSTEM, L_CRIT, 0, "Failed to read configuration file %s", configfile); return 7; } if (thisServer.bootopt & BOOT_CHKCONF) { if (dbg_client) conf_debug_iline(dbg_client); fprintf(stderr, "Configuration file %s checked okay.\n", configfile); return 0; } debug_init(thisServer.bootopt & BOOT_TTY); if (check_pid()) { Debug((DEBUG_FATAL, "Failed to acquire PID file lock after fork")); exit(2); } init_server_identity(); uping_init(); stats_init(); IPcheck_init(); timer_add(timer_init(&connect_timer), try_connections, 0, TT_RELATIVE, 1); timer_add(timer_init(&ping_timer), check_pings, 0, TT_RELATIVE, 1); timer_add(timer_init(&destruct_event_timer), exec_expired_destruct_events, 0, TT_PERIODIC, 60); timer_add(timer_init(&mute_timer), check_expired_mutes, 0, TT_PERIODIC, 30); CurrentTime = time(NULL); SetMe(&me); cli_magic(&me) = CLIENT_MAGIC; cli_from(&me) = &me; make_server(&me); cli_serv(&me)->timestamp = TStime(); /* Abuse own link timestamp as start TS */ cli_serv(&me)->prot = atoi(MAJOR_PROTOCOL); cli_serv(&me)->up = &me; cli_serv(&me)->down = NULL; cli_handler(&me) = SERVER_HANDLER; SetYXXCapacity(&me, MAXCLIENTS); cli_lasttime(&me) = cli_since(&me) = cli_firsttime(&me) = CurrentTime; hAddClient(&me); write_pidfile(); init_counters(); Debug((DEBUG_NOTICE, "Server ready...")); log_write(LS_SYSTEM, L_NOTICE, 0, "Server Ready"); event_loop(); return 0; }
/** * Keyboard soft-irq handler. */ static void kbd_softint(UNUSED_ARG(iptr_t, arg)) { kbd_poll(); timer_add(&kbd_timer); }
void opl3_init(opl_t *opl, int opl_emu) { opl_init(ymf262_timer_set, opl, 0, 1, opl_emu); timer_add(opl_timer_callback00, &opl->timers[0][0], &opl->timers_enable[0][0], (void *)opl); timer_add(opl_timer_callback01, &opl->timers[0][1], &opl->timers_enable[0][1], (void *)opl); }
/* initialize ratelimit module */ static int mod_init(void) { int i; if (rpc_register_array(rpc_methods)!=0) { LM_ERR("failed to register RPC commands\n"); return -1; } rl_lock = lock_alloc(); if (! rl_lock) { LM_ERR("oom in lock_alloc()\n"); return -1; } if (lock_init(rl_lock)==0) { LM_ERR("failed to init lock\n"); return -1; } /* register timer to reset counters */ if ((rl_timer = timer_alloc()) == NULL) { LM_ERR("could not allocate timer\n"); return -1; } timer_init(rl_timer, rl_timer_handle, 0, F_TIMER_FAST); timer_add(rl_timer, MS_TO_TICKS(1000*timer_interval)); network_load_value = shm_malloc(sizeof(int)); if (network_load_value==NULL) { LM_ERR("oom for network_load_value\n"); return -1; } load_value = shm_malloc(sizeof(double)); if (load_value==NULL) { LM_ERR("oom for load_value\n"); return -1; } load_source = shm_malloc(sizeof(int)); if (load_source==NULL) { LM_ERR("oom for load_source\n"); return -1; } pid_kp = shm_malloc(sizeof(double)); if (pid_kp==NULL) { LM_ERR("oom for pid_kp\n"); return -1; } pid_ki = shm_malloc(sizeof(double)); if (pid_ki==NULL) { LM_ERR("oom for pid_ki\n"); return -1; } pid_kd = shm_malloc(sizeof(double)); if (pid_kd==NULL) { LM_ERR("oom for pid_kd\n"); return -1; } pid_setpoint = shm_malloc(sizeof(double)); if (pid_setpoint==NULL) { LM_ERR("oom for pid_setpoint\n"); return -1; } drop_rate = shm_malloc(sizeof(int)); if (drop_rate==NULL) { LM_ERR("oom for drop_rate\n"); return -1; } nqueues = shm_malloc(sizeof(int)); if (nqueues==NULL) { LM_ERR("oom for nqueues\n"); return -1; } rl_dbg_str = shm_malloc(sizeof(str)); if (rl_dbg_str==NULL) { LM_ERR("oom for rl_dbg_str\n"); return -1; } *network_load_value = 0; *load_value = 0.0; *load_source = load_source_mp; *pid_kp = 0.0; *pid_ki = -25.0; *pid_kd = 0.0; *pid_setpoint = 0.01 * (double)cfg_setpoint; *drop_rate = 0; *nqueues = nqueues_mp; rl_dbg_str->s = NULL; rl_dbg_str->len = 0; for (i=0; i<MAX_PIPES; i++) { pipes[i].algo = shm_malloc(sizeof(int)); if (pipes[i].algo==NULL) { LM_ERR("oom for pipes[%d].algo\n", i); return -1; } pipes[i].limit = shm_malloc(sizeof(int)); if (pipes[i].limit==NULL) { LM_ERR("oom for pipes[%d].limit\n", i); return -1; } pipes[i].load = shm_malloc(sizeof(int)); if (pipes[i].load==NULL) { LM_ERR("oom for pipes[%d].load\n", i); return -1; } pipes[i].counter = shm_malloc(sizeof(int)); if (pipes[i].counter==NULL) { LM_ERR("oom for pipes[%d].counter\n", i); return -1; } pipes[i].last_counter = shm_malloc(sizeof(int)); if (pipes[i].last_counter==NULL) { LM_ERR("oom for pipes[%d].last_counter\n", i); return -1; } *pipes[i].algo = pipes[i].algo_mp; *pipes[i].limit = pipes[i].limit_mp; *pipes[i].load = 0; *pipes[i].counter = 0; *pipes[i].last_counter = 0; } for (i=0; i<*nqueues; i++) { queues[i].pipe = shm_malloc(sizeof(int)); if (queues[i].pipe==NULL) { LM_ERR("oom for queues[%d].pipe\n", i); return -1; } queues[i].method = shm_malloc(sizeof(str)); if (queues[i].method==NULL) { LM_ERR("oom for queues[%d].method\n", i); return -1; } *queues[i].pipe = queues[i].pipe_mp; if (queues[i].method_mp.s == NULL) { LM_ERR("unexpected NULL method for queues[%d].method_mp\n", i); return -1; } if(str_cpy(queues[i].method, &queues[i].method_mp)) { LM_ERR("oom str_cpy(queues[%d].method\n", i); return -1; } pkg_free(queues[i].method_mp.s); queues[i].method_mp.s = NULL; queues[i].method_mp.len = 0; } return 0; }
/** * @brief loop process * * @param hmod handler module * @param message message * @param wparam first argument * @param lparam second argument * * @return success 0, failed -1 */ static int thread_proc(HMOD hmod, int message, WPARAM wparam, LPARAM lparam) { switch (message) { case MSG_INIT: { debug(DEBUG, "### '%s'\tMSG_INIT\n", NAME); object_io_t client; ///<新建一个udp client client = new_object_io_udp("udp client"); assert(client); client->_info(); client->_init(&client->parent, hmod, "192.168.199.172:40002"); timer_add(hmod, 1, 1 * ONE_SECOND, client, TIMER_ASYNC); } break; case MSG_TIMER: { int id = (int)wparam; if(id == 1) { char *msg = "test udp client\r\n"; object_io_t client = (object_io_t)lparam; client->_output(&client->parent, msg, strlen(msg)); } } break; case MSG_COMMAND: { } break; case MSG_AIOCONN: { object_io_t client = (object_io_t)lparam; debug(DEBUG, "==> '%s' connect to '%s' success!\n", object_name((object_t)client), client->settings); timer_start(hmod, 1); } break; case MSG_AIOIN: { debug(DEBUG, "==> MSG AIOIN!\n"); int rxnum; char buffer[BUFFER_SIZE]; object_io_t client = (object_io_t)lparam; memset(buffer, 0, BUFFER_SIZE); rxnum = client->_input(&client->parent, buffer, BUFFER_SIZE, TRUE); debug(DEBUG, "==>recv(%d): %s\n", rxnum, buffer); ///<反射 client->_output(&client->parent, buffer, rxnum); } break; case MSG_AIOOUT: { debug(DEBUG, "==> write complete!\n"); } break; case MSG_AIOERR: { debug(DEBUG, "==> MSG AIOERR!\n"); } break; case MSG_AIOBREAK: { debug(DEBUG, "==> MSG AIOBREAK!\n"); object_io_t client = (object_io_t)lparam; debug(DEBUG, "==> '%s' connect to '%s' break!\n", object_name((object_t)client), client->settings); timer_stop(hmod, 1); } break; } return thread_default_process(hmod, message, wparam, lparam); }