Beispiel #1
0
/* Establish a new socket connection to a client */
ClientInfo *
AcceptNewClient(int reqfd)
{
    int		i;
    int		fd;
    __pmSockLen	addrlen;
    int		ok = 0;
    char	buf[MY_BUFLEN];
    char	*bp;
    char	*endp;
    char	*abufp;

    i = NewClient();
    addrlen = __pmSockAddrSize();
    fd = __pmAccept(reqfd, client[i].addr, &addrlen);
    if (fd == -1) {
	__pmNotifyErr(LOG_ERR, "AcceptNewClient(%d) __pmAccept failed: %s",
			reqfd, netstrerror());
	Shutdown();
	exit(1);
    }
    __pmSetSocketIPC(fd);
    if (fd > maxSockFd)
	maxSockFd = fd;
    __pmFD_SET(fd, &sockFds);

    client[i].fd = fd;
    client[i].pmcd_fd = -1;
    client[i].status.connected = 1;
    client[i].status.allowed = 0;
    client[i].pmcd_hostname = NULL;

    /*
     * version negotiation (converse to negotiate_proxy() logic in
     * libpcp
     *
     *   __pmRecv client version message
     *   __pmSend my server version message
     *   __pmRecv pmcd hostname and pmcd port
     */
    for (bp = buf; bp < &buf[MY_BUFLEN]; bp++) {
	if (__pmRecv(fd, bp, 1, 0) != 1) {
	    *bp = '\0';		/* null terminate what we have */
	    bp = &buf[MY_BUFLEN];	/* flag error */
	    break;
	}
	/* end of line means no more ... */
	if (*bp == '\n' || *bp == '\r') {
	    *bp = '\0';
	    break;
	}
    }
    if (bp < &buf[MY_BUFLEN]) {
	/* looks OK so far ... is this a version we can support? */
	if (strcmp(buf, "pmproxy-client 1") == 0) {
	    client[i].version = 1;
	    ok = 1;
	}
    }

    if (!ok) {
#ifdef PCP_DEBUG
	if (pmDebug & DBG_TRACE_CONTEXT) {
	    abufp = __pmSockAddrToString(client[i].addr);
	    __pmNotifyErr(LOG_INFO, "Bad version string from client at %s",
			abufp);
	    free(abufp);
	    fprintf(stderr, "AcceptNewClient: bad version string was \"");
	    for (bp = buf; *bp && bp < &buf[MY_BUFLEN]; bp++)
		fputc(*bp & 0xff, stderr);
	    fprintf(stderr, "\"\n");
	}
#endif
	DeleteClient(&client[i]);
	return NULL;
    }

    if (__pmSend(fd, MY_VERSION, strlen(MY_VERSION), 0) != strlen(MY_VERSION)) {
	abufp = __pmSockAddrToString(client[i].addr);
	__pmNotifyErr(LOG_WARNING, "AcceptNewClient: failed to send version "
			"string (%s) to client at %s\n", MY_VERSION, abufp);
	free(abufp);
	DeleteClient(&client[i]);
	return NULL;
    }

    for (bp = buf; bp < &buf[MY_BUFLEN]; bp++) {
	if (__pmRecv(fd, bp, 1, 0) != 1) {
	    *bp = '\0';		/* null terminate what we have */
	    bp = &buf[MY_BUFLEN];	/* flag error */
	    break;
	}
	/* end of line means no more ... */
	if (*bp == '\n' || *bp == '\r') {
	    *bp = '\0';
	    break;
	}
    }
    if (bp < &buf[MY_BUFLEN]) {
	/* looks OK so far ... get hostname and port */
	for (bp = buf; *bp && *bp != ' '; bp++)
	    ;
	if (bp != buf) {
	    *bp = '\0';
	    client[i].pmcd_hostname = strdup(buf);
	    if (client[i].pmcd_hostname == NULL)
		__pmNoMem("PMCD.hostname", strlen(buf), PM_FATAL_ERR);
	    bp++;
	    client[i].pmcd_port = (int)strtoul(bp, &endp, 10);
	    if (*endp != '\0') {
		abufp = __pmSockAddrToString(client[i].addr);
		__pmNotifyErr(LOG_WARNING, "AcceptNewClient: bad pmcd port "
				"\"%s\" from client at %s", bp, abufp);
		free(abufp);
		DeleteClient(&client[i]);
		return NULL;
	    }
	}
	/* error, fall through */
    }

    if (client[i].pmcd_hostname == NULL) {
	abufp = __pmSockAddrToString(client[i].addr);
	__pmNotifyErr(LOG_WARNING, "AcceptNewClient: failed to get PMCD "
				"hostname (%s) from client at %s", buf, abufp);
	free(abufp);
	DeleteClient(&client[i]);
	return NULL;
    }

#ifdef PCP_DEBUG
    if (pmDebug & DBG_TRACE_CONTEXT) {
	/*
	 * note error message gets appended to once pmcd connection is
	 * made in ClientLoop()
	 */
	abufp = __pmSockAddrToString(client[i].addr);
	fprintf(stderr, "AcceptNewClient [%d] fd=%d from %s to %s (port %s)",
		i, fd, abufp, client[i].pmcd_hostname, bp);
	free(abufp);
    }
#endif

    return &client[i];
}
Beispiel #2
0
int main (int argc, char **argv)
{
  int listenPort = 5002;
  int listenFd;
  struct a_client *theClients=0;
  int nbClient=0;
  struct pollfd *fds=0;
  int maxClientFd=-1;
  long dataLen = 6 *1024 * 1024;
  long stopAfter = 0;
  void *buf = 0;
  int buflen = 0;
  struct timeval startTime;
  struct timeval endTime;


  initBuffer (&buf, &buflen);
  listenFd = socket (AF_INET, SOCK_STREAM, 0);

  if (listenFd < 0)
    {
      fprintf (stderr, "Unable to open socket ? errno %d\n",errno);
      exit (1);
    }
  if (argc >= 2)
    {
      listenPort = atoi (argv[1]);
    }
  if (argc >= 3)
    {
      dataLen= atoi (argv[2]);
    }
  if (argc >= 4)
    {
      stopAfter= atoi (argv[3]);
    }
  struct sockaddr_in addr;
  addr.sin_family = AF_INET;
  addr.sin_port = htons (listenPort);
  addr.sin_addr.s_addr = INADDR_ANY;

  int status;
  status = bind (listenFd, (const struct sockaddr *) &addr, sizeof(addr));
  if (status)
    {
      fprintf (stderr, "Unable to open bind ? errno %d\n",errno);
      exit (2);
    }
  status = listen (listenFd, 256);
  if (status)
    {
      fprintf (stderr, "Unable to open listen ? errno %d \n",errno);
      exit (3);
    }

  while (1)
    {
      fds = realloc (fds, sizeof (struct pollfd) *  nbClient + 1 );

      fds[0].fd = listenFd;
      fds[0].events = POLLIN;
      fds[0].revents = 0;

      int j = 1;
      int c =0;
      for (c=0; c <= maxClientFd ; c++)
        {
          if (theClients[c].sockfd >= 0)
            {
              if (theClients[c].writeLen < dataLen)

                {
                  fds[j].fd = theClients[c].sockfd;
                  fds[j].events = POLLOUT;
                  fds[j].revents = 0;
                  j++;
                }
              else
                {
                  fds[j].fd = theClients[c].sockfd;
                  fds[j].events = POLLIN;
                  fds[j].revents = 0;
                  j++;
                }
            }
        }
      printf ("%d: --> poll j=%d\n",time(NULL), j );
      int ret = poll (fds, j, 29000 * 1000);
      printf ("%d: poll --> %d\n", time(NULL), ret);

      if (ret <= 0)
        {
          exit (0);
        }
      if (ret > 0)
        {
          int i=0;
          for (i=0; i < j; i++)
            {
              if ( fds[i].revents )
                {
                  if (i == 0)
                    { // a new cnxion
                      if ( fds[i].revents & POLLIN  )
                        {
                          int newFd = accept (listenFd, 0, 0);

                          if (newFd >= 0)
                            {
                              if ( 0 == nbClient)
                                {
                                  gettimeofday (&startTime, 0);
                                }
                              NewClient (newFd, &theClients, &nbClient, &maxClientFd);
                            }
                        }
                      if ( fds[i].revents & POLLERR  )
                        {
                          exit (4);
                        }
                    }
                  else
                    { // a client

                      printf ("Client %d revents %d \n", i, fds[i].revents );
                      gettimeofday (&endTime, 0);

                      if ( fds[i].revents & POLLOUT  )
                        {
                          WriteClient (theClients, fds[i].fd, &nbClient, dataLen, buf, buflen, duration (&startTime, &endTime));
                        }
                      if ( ( fds[i].revents & POLLHUP  ) || ( fds[i].revents & POLLIN  )  || ( fds[i].revents & POLLERR  ) )
                        {
                          gettimeofday (&endTime, 0);
                          CloseClient (theClients, fds[i].fd, &nbClient, duration (&startTime, &endTime), dataLen);
                        }
                      if ( stopAfter && ( totalClients >=  stopAfter ))
                        {
                          exit (0);
                        }
                    }
                }
            }
        }
    }
}