/*
 * ms_ping - server message handler
 */
int ms_ping(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  struct Client* acptr;
  char*          origin;
  char*          destination;

  assert(0 != cptr);
  assert(0 != sptr);
  assert(IsServer(cptr));

  if (parc < 2 || EmptyString(parv[1])) {
    /*
     * don't bother sending the error back
     */
    return 0;
  }
  origin      = parv[1];
  destination = parv[2];        /* Will get NULL or pointer (parc >= 2!!) */

  if (parc > 3)
  {
    /* AsLL ping, send reply back */
    int diff = atoi(militime_float(parv[3]));
    sendcmdto_one(&me, CMD_PONG, sptr, "%C %s %s %i %s", &me, origin,
                  parv[3], diff, militime_float(NULL));
    return 0;
  }
  if (!EmptyString(destination) && 0 != ircd_strcmp(destination, cli_name(&me))) {
    if ((acptr = FindServer(destination))) {
      /*
       * Servers can just forward the origin
       */
      sendcmdto_one(sptr, CMD_PING, acptr, "%s :%s", origin, destination);
    }
    else {
      /*
       * this can happen if server split before the ping got here
       */
      send_reply(sptr, ERR_NOSUCHSERVER, destination);
    }
  }
  else {
    /*
     * send pong back
     * NOTE:  sptr is never local so if pong handles numerics everywhere we
     * could send a numeric here.
     */
    sendcmdto_one(&me, CMD_PONG, sptr, "%C :%s", &me, origin);
  }
  return 0;
}
Example #2
0
/* PONG */
void nefarious_cmd_pong(char *servname, char *who)
{
    char *t, *s;
    uint32 ts, tsnow, value;
    t = myStrGetToken(who, '!', 1);
    s = myStrGetToken(t, '.', 0);
    if (!s) {
        ts = 0;
    } else {
        ts = strtol(s, NULL, 10);
    }
    tsnow = time(NULL);
    value = tsnow - ts;
    if (denora->protocoldebug) {
        alog(LOG_PROTOCOL, "PONG: Server Name %s : Who %s", servname, who);
    }
    send_cmd(p10id, "Z %s %ld %ld %ld %s", p10id, (long int) ts,
             (long int) tsnow, (long int) value, militime_float(NULL));
    if (s) {
        free(s);
    }
    if (t) {
        free(t);
    }
}
Example #3
0
/*
 * ms_pong - server message handler
 *
 * parv[0] = sender prefix
 * parv[1] = origin
 * parv[2] = destination
 */
int ms_pong(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  char*          origin;
  char*          destination;
  assert(0 != cptr);
  assert(0 != sptr);
  assert(IsServer(cptr));

  if (parc < 2 || EmptyString(parv[1])) {
    return protocol_violation(sptr,"No Origin on PONG");
  }
  origin      = parv[1];
  destination = parv[2];
  ClearPingSent(cptr);
  ClearPingSent(sptr);
  cli_lasttime(cptr) = CurrentTime;

  if (parc > 5)
  {
    /* AsLL pong */
    cli_serv(cptr)->asll_rtt = atoi(militime_float(parv[3]));
    cli_serv(cptr)->asll_to = atoi(parv[4]);
    cli_serv(cptr)->asll_from = atoi(militime_float(parv[5]));
    cli_serv(cptr)->asll_last = CurrentTime;
    return 0;
  }
  
  if (EmptyString(destination))
    return 0;
  
  if (*destination == '!')
  {
    /* AsLL ping reply from a non-AsLL server */
    cli_serv(cptr)->asll_rtt = atoi(militime_float(destination + 1));
  }
  else if (0 != ircd_strcmp(destination, cli_name(&me)))
  {
    struct Client* acptr;
    if ((acptr = FindClient(destination)))
      sendcmdto_one(sptr, CMD_PONG, acptr, "%s %s", origin, destination);
  }
  return 0;
}
Example #4
0
/* AB Z AB 1116103763 1116103763 0 1116103763.867010 */
void asuka_cmd_pong(char *servname, char *who)
{
    char *t, *s;
    uint32 ts, tsnow, value;

    SET_SEGV_LOCATION();

    t = myStrGetToken(who, '!', 1);
    s = myStrGetToken(t, '.', 0);
    if (!s) {
        ts = 0;
        alog(LOG_NORMAL,
             "This is an error, you should report this as a problem");
        alog(LOG_NORMAL, "Server Name %s : Who %s", servname, who);
    } else {
        ts = strtol(s, NULL, 10);
    }
    tsnow = time(NULL);
    value = tsnow - ts;

    SET_SEGV_LOCATION();

    if (denora->protocoldebug) {
        alog(LOG_PROTOCOL, "PONG: Server Name %s : Who %s", servname, who);
    }
    send_cmd(p10id, "Z %s %ld %ld %ld %s", p10id, (long int) ts,
             (long int) tsnow, (long int) value, militime_float(NULL));

    SET_SEGV_LOCATION();

    if (s) {
        free(s);
    }
    if (t) {
        free(t);
    }
}
Example #5
0
void asuka_cmd_ping(char *server)
{
    /* AB G !1115872042.64217 denora.nomadirc.net 1115872042.64217 */
    send_cmd(p10id, "G !%s %s %s", militime_float(NULL), server,
             militime_float(NULL));
}
Example #6
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);
}