Exemplo n.º 1
0
void
CleanupClient(ClientInfo *cp, int sts)
{
    char	*caddr;
    int		i, msg;
    int		force;

    force = pmDebug & DBG_TRACE_APPL0;

    if (sts != 0 || force) {
	/* for access violations, only print the message if this host hasn't
	 * been dinged for an access violation since startup or reconfiguration
	 */
	if (sts == PM_ERR_PERMISSION || sts == PM_ERR_CONNLIMIT) {
	    if ( (msg = AddBadHost(cp->addr)) ) {
		caddr = __pmSockAddrToString(cp->addr);
		fprintf(stderr, "access violation from host %s\n", caddr);
		free(caddr);
	    }
	}
	else
	    msg = 0;

	if (msg || force) {
	    for (i = 0; i < nClients; i++) {
		if (cp == &client[i])
		    break;
	    }
	    fprintf(stderr, "endclient client[%d]: (fd %d) %s (%d)\n",
		    i, cp->fd, pmErrStr(sts), sts);
	}
    }

    /* If the client is being cleaned up because its connection was refused
     * don't do this because it hasn't actually contributed to the connection
     * count
     */
    if (sts != PM_ERR_PERMISSION && sts != PM_ERR_CONNLIMIT)
        __pmAccDelClient(cp->addr);

    pmcd_trace(TR_DEL_CLIENT, cp->fd, sts, 0);
    DeleteClient(cp);

    if (maxClientFd < maxReqPortFd)
	maxClientFd = maxReqPortFd;

    for (i = 0; i < nAgents; i++)
	if (agent[i].profClient == cp)
	    agent[i].profClient = NULL;
}
Exemplo n.º 2
0
Arquivo: client.c Projeto: Aconex/pcp
void
ShowClients(FILE *f)
{
    int			i;
    char		*sbuf;
    char		*hostName;

    fprintf(f, "     fd  client connection from                    ipc ver  operations denied\n");
    fprintf(f, "     ==  ========================================  =======  =================\n");
    for (i = 0; i < nClients; i++) {
	if (client[i].status.connected == 0)
	    continue;

	fprintf(f, "    %3d  ", client[i].fd);

	hostName = __pmGetNameInfo(client[i].addr);
	if (hostName == NULL) {
	    sbuf = __pmSockAddrToString(client[i].addr);
	    fprintf(f, "%s", sbuf);
	    free(sbuf);
	} else {
	    fprintf(f, "%-40.40s", hostName);
	    free(hostName);
	}
	fprintf(f, "  %7d", __pmVersionIPC(client[i].fd));

	if (client[i].denyOps != 0) {
	    fprintf(f, "  ");
	    if (client[i].denyOps & PMCD_OP_FETCH)
		fprintf(f, "fetch ");
	    if (client[i].denyOps & PMCD_OP_STORE)
		fprintf(f, "store ");
	}

	fputc('\n', f);
    }
    fputc('\n', f);
}
Exemplo n.º 3
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];
}