示例#1
0
文件: uping.c 项目: evilnet/nefarious
/** Start sending upings to a server.
 * @param[in] sptr Client requesting the upings.
 * @param[in] aconf ConfItem containing the address to ping.
 * @param[in] port Port number to ping.
 * @param[in] count Number of times to ping (should be at least 20).
 * @return Zero.
 */
int uping_server(struct Client* sptr, struct ConfItem* aconf, int port, int count)
{
  int fd;
  struct UPing* pptr;

  assert(0 != sptr);
  assert(0 != aconf);

  if (INADDR_NONE == aconf->ipnum.s_addr) {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :UPING: Host lookup failed for "
		  "%s", sptr, aconf->name);
    return 0;
  }

  if (IsUPing(sptr))
    uping_cancel(sptr, sptr);  /* Cancel previous ping request */

  if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :UPING: Unable to create udp "
		  "ping socket", sptr);
    return 0;
  }

  if (!os_set_nonblocking(fd)) {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :UPING: Can't set fd non-"
		  "blocking", sptr);
    close(fd);
    return 0;
  }
  pptr = (struct UPing*) MyMalloc(sizeof(struct UPing));
  assert(0 != pptr);
  memset(pptr, 0, sizeof(struct UPing));

  if (!socket_add(&pptr->socket, uping_read_callback, (void*) pptr,
		  SS_DATAGRAM, SOCK_EVENT_READABLE, fd)) {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :UPING: Can't queue fd for "
		  "reading", sptr);
    close(fd);
    MyFree(pptr);
    return 0;
  }

  pptr->fd                  = fd;
  pptr->sin.sin_port        = htons(port);
  pptr->sin.sin_addr.s_addr = aconf->ipnum.s_addr;
  pptr->sin.sin_family      = AF_INET;
  pptr->count               = IRCD_MIN(20, count);
  pptr->client              = sptr;
  pptr->index               = -1;
  pptr->freeable            = UPING_PENDING_SOCKET;
  strcpy(pptr->name, aconf->name);

  pptr->next = pingList;
  pingList   = pptr;

  SetUPing(sptr);
  uping_start(pptr);
  return 0;
}
示例#2
0
/** Start sending upings to a server.
 * @param[in] sptr Client requesting the upings.
 * @param[in] aconf ConfItem containing the address to ping.
 * @param[in] port Port number to ping.
 * @param[in] count Number of times to ping (should be at least 20).
 * @return Zero.
 */
int uping_server(struct Client* sptr, struct ConfItem* aconf, int port, int count)
{
  int fd;
  int family = 0;
  struct UPing* pptr;
  struct irc_sockaddr *local;

  assert(0 != sptr);
  assert(0 != aconf);

  if (!irc_in_addr_valid(&aconf->address.addr)) {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :UPING: Host lookup failed for "
		  "%s", sptr, aconf->name);
    return 0;
  }

  if (IsUPing(sptr))
    uping_cancel(sptr, sptr);  /* Cancel previous ping request */

  if (irc_in_addr_is_ipv4(&aconf->address.addr)) {
    local = &VirtualHost_v4;
    family = AF_INET;
  } else {
    local = &VirtualHost_v6;
  }
  fd = os_socket(local, SOCK_DGRAM, "Outbound uping socket", family);
  if (fd < 0)
    return 0;

  pptr = (struct UPing*) MyMalloc(sizeof(struct UPing));
  assert(0 != pptr);
  memset(pptr, 0, sizeof(struct UPing));

  if (!socket_add(&pptr->socket, uping_read_callback, (void*) pptr,
		  SS_DATAGRAM, SOCK_EVENT_READABLE, fd)) {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :UPING: Can't queue fd for "
		  "reading", sptr);
    close(fd);
    MyFree(pptr);
    return 0;
  }

  pptr->fd                  = fd;
  memcpy(&pptr->addr.addr, &aconf->address.addr, sizeof(pptr->addr.addr));
  pptr->addr.port           = port;
  pptr->count               = IRCD_MIN(20, count);
  pptr->client              = sptr;
  pptr->freeable            = UPING_PENDING_SOCKET;
  strcpy(pptr->name, aconf->name);

  pptr->next = pingList;
  pingList   = pptr;

  SetUPing(sptr);
  uping_start(pptr);
  return 0;
}