Ejemplo n.º 1
0
/** 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;
}
Ejemplo n.º 2
0
void init_app_timers(void) {
  timer_add(&screenTimer, 50, &screen_timer_callback, NULL );
  timer_add(&encTimer, 50, &enc_timer_callback, NULL );
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
/* 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;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
0
/** Initialize the IPcheck subsystem. */
void IPcheck_init(void)
{
  timer_add(timer_init(&expireTimer), ip_registry_expire, 0, TT_PERIODIC, 60);
}
Ejemplo n.º 7
0
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);
}
Ejemplo n.º 8
0
Archivo: main.c Proyecto: Ysum/mod
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();
	}
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
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));
}
Ejemplo n.º 11
0
Archivo: run.c Proyecto: chr15m/ccan
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();
  }
}
Ejemplo n.º 13
0
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);
}
Ejemplo n.º 14
0
void disc_reset()
{
        curdrive = 0;
        disc_period = 32;
	timer_add(disc_poll, &disc_poll_time, &motoron, NULL);
}
Ejemplo n.º 15
0
/** 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));
}
Ejemplo n.º 16
0
Archivo: main.c Proyecto: Ysum/mod
// 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 );
}
Ejemplo n.º 17
0
// 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 );
}
Ejemplo n.º 18
0
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;
}
Ejemplo n.º 19
0
/** 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,
};
Ejemplo n.º 21
0
/** 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);
}
Ejemplo n.º 22
0
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);
}
Ejemplo n.º 23
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;
}
Ejemplo n.º 24
0
Archivo: kbd.c Proyecto: mtarek/BeRTOS
/**
 * Keyboard soft-irq handler.
 */
static void kbd_softint(UNUSED_ARG(iptr_t, arg))
{
    kbd_poll();
    timer_add(&kbd_timer);
}
Ejemplo n.º 25
0
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);
}
Ejemplo n.º 26
0
/* 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;
}
Ejemplo n.º 27
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);
}