コード例 #1
0
ファイル: ri_tcp_sock.c プロジェクト: JianlongCao/qeo-core
static void tcp_close_pending_connection (TCP_FD *pp)
{
	int	r;

	if (tmr_active (&pp->timer))
		tmr_stop (&pp->timer);

	ctrc_printd (TCPS_ID, TCPS_CLOSE_PEND, &pp->fd, sizeof (pp->fd));
	sock_fd_remove_socket (pp->fd);
	r = close (pp->fd);
	trace_server ("close", r, pp->fd);
	if (r)
		perror ("tcp_close_pending_connection: close()");
	pp->fd = 0;
	tcp_pending_free (pp);
}
コード例 #2
0
ファイル: trace.c プロジェクト: quakenet/newserv
/* handle remote trace request
 *
 * <source numeric> TRACE/TR <target> <target server numeric>
 *
 * cargv[0] = target
 *            as given by source, can be a nick or a server (may contain wildcards)
 * cargv[1] = target server numeric
 * 
 */
int handletracemsg(void *source, int cargc, char **cargv) {

  nick *snick;                        /* struct nick for source nick */
  nick *tnick;                        /* struct nick for target nick */
  nick **lnick;                       /* struct nick for looping local users */
  int c;                              /* loop variable */
  int opers = 0;                      /* number of operators */
  int users = 0;                      /* number of users */
  int servers = 0;                    /* number of servers */
  int doall, wilds, dow;              /* determine what to show */
  char *sourcenum = (char *)source;   /* source user numeric */
  char *target;                       /* target parameter - as given by the source user */


  /* check parameters */
  if (cargc < 2) {
    miscreply_needmoreparams(sourcenum, "TRACE");
    return CMD_OK;
  }

  /* get the parameters */
  target = cargv[0];

  /* find source user */ 
  if (!(snick = miscreply_finduser(sourcenum, "TRACE")))
    return CMD_OK;

  /* doall, wilds, dow */
  doall = match2strings(target, myserver->content);
  wilds = strchr(target, '*') || strchr(target, '?');
  dow = wilds || doall;


  /* find target user */
  if ((tnick = getnickbynick(target))) {

    /* my user */
    if (mylongnum == homeserver(tnick->numeric))
      trace_user(sourcenum, tnick);
  }


  /* source user is an operator */
  else if (IsOper(snick)) {

    /* show servers */
    servers = trace_server(sourcenum, target, doall);

    /* do all or wilds */
    if (dow) {

      /* loop over all local users */
      lnick = servernicks[mylongnum];
      for (c = 0; c < serverlist[mylongnum].maxusernum; c++) {

        if (lnick[c] == NULL)   /* no user */
          continue;

        /* target is invisible (mode +i), target is not an operator */
        if (IsInvisible(lnick[c]) && dow && !IsOper(lnick[c]))
          continue;

        /* dont show all, do wildcards and no match */
        if (!doall && wilds && !match2strings(target, lnick[c]->nick))
          continue;

        if (IsOper(lnick[c]))
          opers++;
        else
          users++;
        trace_user(sourcenum, lnick[c]);
      }
      /*
       * class has no meaning here,
       * but showing the total count for users/opers/servers might be useful anyway
       *
       * 209 RPL_TRACECLASS "source 209 target Class class count"
       *                    "irc.netsplit.net 209 foobar Class users 2"
       */
      if (users)
        irc_send("%s 209 %s Class users %d", getmynumeric(), sourcenum, users);
      if (opers)
        irc_send("%s 209 %s Class opers %d", getmynumeric(), sourcenum, opers);
      if (servers)
        irc_send("%s 209 %s Class servers %d", getmynumeric(), sourcenum, servers);
    }
  }


  /*
   * 262 RPL_TRACEEND "source 262 target :End of TRACE"
   *                  "irc.netsplit.net 262 foobar :End of TRACE"
   */
  irc_send("%s 262 %s :End of TRACE", getmynumeric(), sourcenum);

  return CMD_OK;
}
コード例 #3
0
ファイル: ri_tcp_sock.c プロジェクト: JianlongCao/qeo-core
static void tcp_server_accept (SOCKET fd, short revents, void *arg)
{
	IP_CX			*scxp = (IP_CX *) arg;
	TCP_FD			*pp;
	struct sockaddr_in	peer_addr;
#ifdef DDS_IPV6
	struct sockaddr_in6	peer_addr_v6;
#endif
	struct sockaddr		*caddr;
	socklen_t		size;
	uint32_t		a4;
	int			r;

	trace_poll_events (fd, revents, arg);

	memset (&scxp->dst_addr, 0, sizeof (scxp->dst_addr));
	if (scxp->locator->locator.kind == LOCATOR_KIND_TCPv4) {
		peer_addr.sin_family = AF_INET;
		caddr = (struct sockaddr *) &peer_addr;
		size = sizeof (struct sockaddr_in);
	}
#ifdef DDS_IPV6
	else if (scxp->locator->locator.kind == LOCATOR_KIND_TCPv6) {
		peer_addr_v6.sin6_family = AF_INET6;
		caddr = (struct sockaddr *) &peer_addr_v6;
		size = sizeof (struct sockaddr_in6);
	}
#endif
	else {
		warn_printf ("TCP(S): unknown address family!");
		return;
	}
#ifdef TCP_ACCEPT_DELAY_MS
	usleep (TCP_ACCEPT_DELAY_MS * 1000);
#endif
	r = accept (fd, caddr, &size);

	ctrc_begind (TCPS_ID, TCPS_SERVER_EV, &fd, sizeof (fd));
	ctrc_contd (&revents, sizeof (revents));
	ctrc_contd (caddr, size);
	ctrc_contd (&r, sizeof (r));
	ctrc_endd ();

	trace_server ("accept", r, fd);
	if (r < 0) {
		perror ("tcp_server_accept: accept()");
		log_printf (RTPS_ID, 0, "tcp_server_accept: accept() failed - errno = %d.\r\n", ERRNO);
		return;
	}

#ifdef DDS_TCP_NODELAY
	sock_set_tcp_nodelay (r);
#endif

	/* Create a new pending TCP connection. */
	pp = xmalloc (sizeof (TCP_FD));
	if (!pp) {
		ctrc_printd (TCPS_ID, TCPS_FD_NOMEM, &r, sizeof (r));
		close (r); /* bad reuse of variable in error case */
		trace_server ("close", 0, r);
		log_printf (RTPS_ID, 0, "TCP(S): allocation failure!\r\n");
		return;
	}
	memset (pp, 0, sizeof (TCP_FD));
	pp->fd = r;
	if (scxp->locator->locator.kind == LOCATOR_KIND_TCPv4) {
		a4 = ntohl (peer_addr.sin_addr.s_addr);
		memset (pp->dst_addr, 0, 12);
		pp->dst_addr [12] = a4 >> 24;
		pp->dst_addr [13] = (a4 >> 16) & 0xff;
		pp->dst_addr [14] = (a4 >> 8) & 0xff;
		pp->dst_addr [15] = a4 & 0xff;
		pp->dst_port = ntohs (peer_addr.sin_port);
	}
コード例 #4
0
ファイル: ri_tcp_sock.c プロジェクト: JianlongCao/qeo-core
static int tcp_do_connect (TCP_CON_REQ_ST *p)
{
	TCP_CON_LIST_ST		*hp;
	TCP_DATA		*dp;
	struct sockaddr_in	sa_v4;
#ifdef DDS_IPV6
	struct sockaddr_in6	sa_v6;
#endif
	struct sockaddr		*sa;
	socklen_t		len;
	unsigned		family;
	short			events;
	int			fd, r, err;
#ifdef __APPLE__
	int			yes = 1;
#endif

	trc_con1 ("tcp_do_connect(cp=%p);\r\n", (void *) p);
	do {
		/* No connect() in progress currently! */
		hp = p->head;
		if ((hp->locator.kind & LOCATOR_KINDS_IPv4) != 0) {
			sa_v4.sin_family = family = AF_INET;
			sa_v4.sin_port = htons (hp->locator.port);
			sa = (struct sockaddr *) &sa_v4;
			len = sizeof (sa_v4);
			sa_v4.sin_addr.s_addr = htonl ((hp->locator.address [12] << 24) |
						       (hp->locator.address [13] << 16) |
						       (hp->locator.address [14] << 8) |
						        hp->locator.address [15]);
			ctrc_printd (TCPS_ID, TCPS_DO_CON, hp->locator.address + 12, 4);
		}
#ifdef DDS_IPV6
		else if ((hp->locator.kind & LOCATOR_KINDS_IPv6) != 0) {
			sa_v6.sin6_family = family = AF_INET6;
			memcpy (sa_v6.sin6_addr.s6_addr, hp->locator.address, 16);
			sa_v6.sin6_port = htons (hp->locator.port);
			sa = (struct sockaddr *) &sa_v6;
			len = sizeof (sa_v6);
			ctrc_printd (TCPS_ID, TCPS_DO_CON, hp->locator.address, 16);
		}
#endif
		else {
			log_printf (RTPS_ID, 0, "tcp_do_connect: invalid locator kind!\r\n");
			return (-2);
		}
		dp = xmalloc (sizeof (TCP_DATA));
		if (!dp) {
			warn_printf ("tcp_connect: out of memory for TCP context!");
			return (-2);
		}
		dp->send_msg = dp->recv_msg = NULL;

		fd = socket (family, SOCK_STREAM, IPPROTO_TCP);
		trace_client ("socket", fd, -1);
		if (fd < 0) {
			xfree (dp);
			/*perror ("tcp_do_connect: socket()");*/
			log_printf (RTPS_ID, 0, "tcp_do_connect: socket() failed - errno = %d.\r\n", ERRNO);
			return (-2);
		}
		p->cxp->fd = fd;
		p->cxp->fd_owner = 1;
		p->cxp->sproto = dp;

#ifdef __APPLE__
		/* MSG_NOSIGNAL does not exist for Apple OS, but a equivalent socket option is available */
		if (setsockopt (fd, SOL_SOCKET, SO_NOSIGPIPE, &yes, sizeof (yes)) < 0)
			perror ("tcp_do_connect: setsockopt()");
#endif
#ifdef DDS_TCP_NODELAY
		sock_set_tcp_nodelay (fd);
#endif
		sock_set_socket_nonblocking (fd);
		events = POLLIN | POLLPRI | POLLHUP | POLLNVAL;
		for (;;) {
			r = connect (fd, sa, len);

			ctrc_begind (TCPS_ID, TCPS_SYS_CON, &fd, sizeof (fd));
			ctrc_contd (&r, sizeof (r));
			ctrc_endd ();

			trace_client ("connect", r, fd);
			if (r == -1) {
				err = ERRNO;
				if (err == EINTR)
					continue;

				if (err != EINPROGRESS) {
					ctrc_printd (TCPS_ID, TCPS_CON_ERR, &fd, sizeof (fd));
					/*perror ("tcp_do_connect: connect()");*/
					log_printf (RTPS_ID, 0, "tcp_do_connect: connect() failed - errno = %d.\r\n", err);
					close (fd);
					trace_server ("close", r, fd);
					p->cxp->cx_state = CXS_WRETRY;
					p->cxp->fd = 0;
					p->cxp->fd_owner = 0;
				}
				else {
					log_printf (RTPS_ID, 0, "TCP: connecting to server [%d] ...\r\n", fd);
					p->cxp->cx_state = CXS_CONNECT;
					sock_fd_add_socket (fd, events | POLLOUT, tcp_wait_connect_complete, p, "DDS.TCP-C");
					ctrc_printd (TCPS_ID, TCPS_CON_WAIT, &fd, sizeof (fd));
					return (-1);
				}
			}
			else {
				log_printf (RTPS_ID, 0, "TCP: connected to server [%d]\r\n", fd);
				p->cxp->cx_state = CXS_OPEN;
				ctrc_printd (TCPS_ID, TCPS_CON_OK, &fd, sizeof (fd));
				sock_fd_add_socket (fd, events, tcp_socket_activity, p->cxp, "DDS.TCP-C");
			}
			break;
		}
		p = tcp_clear_pending_connect (p);
	}
	while (p);
	return (r);
}