/* Handle ipv4 or ipv6 connection */ int RemoteConnect(char *host,int forceipv4) { int err; #if defined(HAVE_GETADDRINFO) && !defined(DARWIN) if (forceipv4 == 'n') { struct addrinfo query, *response, *ap; struct addrinfo query2, *response2, *ap2; int err,connected = false; memset(&query,0,sizeof(struct addrinfo)); query.ai_family = AF_UNSPEC; query.ai_socktype = SOCK_STREAM; if ((err = getaddrinfo(host,"5308",&query,&response)) != 0) { snprintf(g_output,CF_BUFSIZE, "Unable to lookup hostname or cfengine service: %s", gai_strerror(err)); CfLog(cfinform,g_output,""); return false; } for (ap = response; ap != NULL; ap = ap->ai_next) { Verbose("Connect to %s = %s on port cfengine\n", host,sockaddr_ntop(ap->ai_addr)); if ((g_conn->sd = socket(ap->ai_family,ap->ai_socktype,ap->ai_protocol)) == -1) { CfLog(cfinform,"Couldn't open a socket","socket"); continue; } if (g_bindinterface[0] != '\0') { memset(&query2,0,sizeof(struct addrinfo)); query.ai_family = AF_UNSPEC; query.ai_socktype = SOCK_STREAM; if ((err = getaddrinfo(g_bindinterface,NULL,&query2, &response2)) != 0) { snprintf(g_output,CF_BUFSIZE, "Unable to lookup hostname or " "cfengine service: %s", gai_strerror(err)); CfLog(cferror,g_output,""); return false; } for (ap2 = response2; ap2 != NULL; ap2 = ap2->ai_next) { if (bind(g_conn->sd, ap2->ai_addr, ap2->ai_addrlen) == 0) { freeaddrinfo(response2); break; } } if (response2) { free(response2); } } signal(SIGALRM,(void *)TimeOut); alarm(g_cf_timeout); if (connect(g_conn->sd,ap->ai_addr,ap->ai_addrlen) >= 0) { connected = true; alarm(0); signal(SIGALRM,SIG_DFL); break; } alarm(0); signal(SIGALRM,SIG_DFL); } if (connected) { g_conn->family = ap->ai_family; snprintf(g_conn->remoteip,CF_MAX_IP_LEN-1,"%s", sockaddr_ntop(ap->ai_addr)); } else { close(g_conn->sd); snprintf(g_output, CF_BUFSIZE*2, "Couldn't connect to host %s\n", host); g_conn->sd = CF_NOT_CONNECTED; } if (response != NULL) { freeaddrinfo(response); } if (!connected) { return false; } } else #endif /* ---------------------- only have ipv4 ---------------------------------*/ { struct hostent *hp; struct sockaddr_in cin; memset(&cin,0,sizeof(cin)); if ((hp = gethostbyname(host)) == NULL) { snprintf(g_output, CF_BUFSIZE, "Unable to look up " "IP address of %s", host); CfLog(cferror,g_output,"gethostbyname"); return false; } cin.sin_port = CfenginePort(); cin.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr; cin.sin_family = AF_INET; Verbose("Connect to %s = %s, port h=%d\n", host,inet_ntoa(cin.sin_addr),htons(g_portnumber)); if ((g_conn->sd = socket(AF_INET,SOCK_STREAM,0)) == -1) { CfLog(cferror,"Couldn't open a socket","socket"); return false; } if (g_bindinterface[0] != '\0') { Verbose("Cannot bind interface with this OS.\n"); /* Could fix this - any point? */ } g_conn->family = AF_INET; snprintf(g_conn->remoteip, CF_MAX_IP_LEN-1, "%s", inet_ntoa(cin.sin_addr)); signal(SIGALRM,(void *)TimeOut); alarm(g_cf_timeout); if (err=connect(g_conn->sd,(void *)&cin,sizeof(cin)) == -1) { snprintf(g_output, CF_BUFSIZE*2, "Couldn't connect to host %s\n", host); CfLog(cfinform,g_output,"connect"); return false; } alarm(0); signal(SIGALRM,SIG_DFL); } LastSeen(host,cf_connect); return true; }
int RemoteConnect(char *host,char forceipv4,short oldport, char *newport) { int err; #if defined(HAVE_GETADDRINFO) if (forceipv4 == 'n') { struct addrinfo query, *response, *ap; struct addrinfo query2, *response2, *ap2; int err,connected = false; memset(&query,0,sizeof(struct addrinfo)); query.ai_family = AF_UNSPEC; query.ai_socktype = SOCK_STREAM; if ((err = getaddrinfo(host,newport,&query,&response)) != 0) { snprintf(OUTPUT,CF_BUFSIZE,"Unable to find hostname or cfengine service: (%s/%s) %s",host,STR_CFENGINEPORT,gai_strerror(err)); CfLog(cfinform,OUTPUT,""); return false; } for (ap = response; ap != NULL; ap = ap->ai_next) { Verbose("Connect to %s = %s on port %s\n",host,sockaddr_ntop(ap->ai_addr),newport); if ((CONN->sd = socket(ap->ai_family,ap->ai_socktype,ap->ai_protocol)) == -1) { CfLog(cfinform,"Couldn't open a socket","socket"); continue; } if (BINDINTERFACE[0] != '\0') { memset(&query2,0,sizeof(struct addrinfo)); query.ai_family = AF_UNSPEC; query.ai_socktype = SOCK_STREAM; if ((err = getaddrinfo(BINDINTERFACE,NULL,&query2,&response2)) != 0) { snprintf(OUTPUT,CF_BUFSIZE,"Unable to lookup hostname or cfengine service: %s",gai_strerror(err)); CfLog(cferror,OUTPUT,""); return false; } for (ap2 = response2; ap2 != NULL; ap2 = ap2->ai_next) { if (bind(CONN->sd, ap2->ai_addr, ap2->ai_addrlen) == 0) { freeaddrinfo(response2); response2 = NULL; break; } } if (response2) { freeaddrinfo(response2); } } signal(SIGALRM,(void *)TimeOut); alarm(CF_TIMEOUT); if (connect(CONN->sd,ap->ai_addr,ap->ai_addrlen) >= 0) { connected = true; alarm(0); signal(SIGALRM,SIG_DFL); break; } alarm(0); signal(SIGALRM,SIG_DFL); } if (connected) { CONN->family = ap->ai_family; snprintf(CONN->remoteip,CF_MAX_IP_LEN-1,"%s",sockaddr_ntop(ap->ai_addr)); } else { close(CONN->sd); snprintf(OUTPUT,CF_BUFSIZE*2,"Couldn't connect to host %s\n",host); CONN->sd = CF_NOT_CONNECTED; } if (response != NULL) { freeaddrinfo(response); } if (!connected) { return false; } } else #endif /* ---------------------- only have ipv4 ---------------------------------*/ { struct hostent *hp; struct sockaddr_in cin; memset(&cin,0,sizeof(cin)); if ((hp = gethostbyname(host)) == NULL) { snprintf(OUTPUT,CF_BUFSIZE,"Unable to look up IP address of %s",host); CfLog(cferror,OUTPUT,"gethostbyname"); return false; } cin.sin_port = oldport; cin.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr; cin.sin_family = AF_INET; Verbose("Connect to %s = %s, port =%u\n",host,inet_ntoa(cin.sin_addr),SHORT_CFENGINEPORT); if ((CONN->sd = socket(AF_INET,SOCK_STREAM,0)) == -1) { CfLog(cferror,"Couldn't open a socket","socket"); return false; } if (BINDINTERFACE[0] != '\0') { Verbose("Cannot bind interface with this OS.\n"); /* Could fix this - any point? */ } CONN->family = AF_INET; snprintf(CONN->remoteip,CF_MAX_IP_LEN-1,"%s",inet_ntoa(cin.sin_addr)); signal(SIGALRM,(void *)TimeOut); alarm(CF_TIMEOUT); if (err=connect(CONN->sd,(void *)&cin,sizeof(cin)) == -1) { snprintf(OUTPUT,CF_BUFSIZE*2,"Couldn't connect to host %s\n",host); CfLog(cfinform,OUTPUT,"connect"); return false; } alarm(0); signal(SIGALRM,SIG_DFL); } LastSeen(host,cf_connect); return true; }