/* Establish a new socket connection to a client */ ClientInfo * AcceptNewClient(int reqfd) { static unsigned int seq = 0; int i, fd; __pmSockLen addrlen; struct timeval now; i = NewClient(); addrlen = __pmSockAddrSize(); fd = __pmAccept(reqfd, client[i].addr, &addrlen); if (fd == -1) { if (neterror() == EPERM) { __pmNotifyErr(LOG_NOTICE, "AcceptNewClient(%d): " "Permission Denied\n", reqfd); client[i].fd = -1; DeleteClient(&client[i]); return NULL; } else { __pmNotifyErr(LOG_ERR, "AcceptNewClient(%d) __pmAccept: %s\n", reqfd, netstrerror()); Shutdown(); exit(1); } } if (fd > maxClientFd) maxClientFd = fd; pmcd_openfds_sethi(fd); __pmFD_SET(fd, &clientFds); __pmSetVersionIPC(fd, UNKNOWN_VERSION); /* before negotiation */ __pmSetSocketIPC(fd); client[i].fd = fd; client[i].status.connected = 1; client[i].status.changes = 0; memset(&client[i].attrs, 0, sizeof(__pmHashCtl)); /* * Note seq needs to be unique, but we're using a free running counter * and not bothering to check here ... unless we churn through * 4,294,967,296 (2^32) clients while one client remains connected * we won't have a problem */ client[i].seq = seq++; __pmtimevalNow(&now); client[i].start = now.tv_sec; #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "AcceptNewClient(%d): client[%d] (fd %d)\n", reqfd, i, fd); #endif pmcd_trace(TR_ADD_CLIENT, i, 0, 0); return &client[i]; }
/* 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]; }