00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "ccs-client.h"
00040 #include <stdio.h>
00041 #include <string.h>
00042 #include <stdlib.h>
00043
00044 #ifndef CMK_NO_SOCKETS
00045
00046
00047 #include "sockRoutines.C"
00048 #include "ccs-auth.C"
00049
00050 #define DEBUGF(x)
00051
00052
00053
00054 static void parseInfo(CcsServer *svr,const void *data)
00055 {
00056
00057 const ChMessageInt_t *d=(const ChMessageInt_t *)data;
00058 int i,index=0;
00059
00060 svr->numNodes=ChMessageInt(d[index++]);
00061 svr->numProcs = (int *) malloc(svr->numNodes * sizeof(int));
00062 svr->numPes = 0;
00063 for(i=0;i<svr->numNodes;i++)
00064 svr->numPes+=svr->numProcs[i]=ChMessageInt(d[index++]);
00065 }
00066
00067 static void printSvr(CcsServer *svr)
00068 {
00069 char ipBuf[200];
00070 int i;
00071 DEBUGF(("hostIP: %s\n", skt_print_ip(ipBuf,svr->hostIP)));
00072 DEBUGF(("hostPort: %d\n", svr->hostPort));
00073 DEBUGF(("authentication: %d\n", svr->isAuth));
00074 DEBUGF(("replyFd: %d\n", svr->replyFd));
00075 DEBUGF(("numNodes: %d\n", svr->numNodes));
00076 DEBUGF(("numPes: %d\n", svr->numPes));
00077 for(i=0;i<svr->numNodes;i++) {
00078 DEBUGF(("Node[%d] has %d processors\n",i, svr->numProcs[i]));
00079 }
00080 }
00081
00082
00083
00084 static const char *CcsImpl_authInit(SOCKET fd,CcsServer *svr)
00085 {
00086 struct {
00087 unsigned char type[4];
00088 ChMessageInt_t s1;
00089 } request;
00090 int s1;
00091 ChMessageInt_t s2;
00092 SHA1_hash_t s2hash;
00093 struct {
00094 SHA1_hash_t s1hash;
00095 ChMessageInt_t clientID;
00096 ChMessageInt_t clientSalt;
00097 } reply;
00098 if (fd==-1)
00099 return "ERROR> Contacting server";
00100 request.type[0]=0x80;
00101 request.type[1]=0x00;
00102 request.type[2]=0x01;
00103 request.type[3]=svr->level;
00104 s1=CCS_RAND_next(&svr->rand);
00105 request.s1=ChMessageInt_new(s1);
00106 if (-1==skt_sendN(fd,&request,sizeof(request)))
00107 return "ERROR> AuthInit request send";
00108 if (-1==skt_recvN(fd,&s2,sizeof(s2)))
00109 return "ERROR> AuthInit challenge recv";
00110 CCS_AUTH_hash(&svr->key,ChMessageInt(s2),NULL,&s2hash);
00111 if (-1==skt_sendN(fd,&s2hash,sizeof(s2hash)))
00112 return "ERROR> AuthInit challenge reply send";
00113 if (-1==skt_recvN(fd,&reply,sizeof(reply)))
00114 return "ERROR> AuthInit final recv (authentication failure?)";
00115 if (CCS_AUTH_differ(&svr->key,s1,NULL,&reply.s1hash))
00116 return "ERROR> AuthInit server key does not match";
00117
00118 svr->clientID=ChMessageInt(reply.clientID);
00119 svr->clientSalt=ChMessageInt(reply.clientSalt);
00120 return 0;
00121 }
00122
00123
00128 int CcsConnect(CcsServer *svr, const char *host, int port,const CcsSec_secretKey *key){
00129 return CcsConnectWithTimeout(svr, host, port, key, 120);
00130 }
00131
00132 int CcsConnectWithTimeout(CcsServer *svr, const char *host, int port,
00133 const CcsSec_secretKey *key, int timeout)
00134 {
00135 skt_init();
00136 return CcsConnectIpWithTimeout(svr,skt_lookup_ip(host),port,key, timeout);
00137 }
00138
00139 int CcsConnectIp(CcsServer *svr, skt_ip_t ip, int port,const CcsSec_secretKey *key){
00140 return CcsConnectIpWithTimeout(svr, ip, port, key, 120);
00141 }
00142
00143 int CcsConnectIpWithTimeout(CcsServer *svr, skt_ip_t ip, int port,
00144 const CcsSec_secretKey *key, int timeout)
00145 {
00146 int msg_len;void *msg_data;
00147 skt_init();
00148 svr->hostIP = ip;
00149 svr->hostPort = port;
00150 svr->replyFd=INVALID_SOCKET;
00151
00152 svr->clientID=svr->clientSalt=-1;
00153 if (key==NULL)
00154 svr->isAuth=0;
00155 else
00156 {
00157 SOCKET fd;
00158 const char *err;
00159 svr->isAuth=1;
00160 svr->level=0;
00161 svr->key=*key;
00162 CCS_RAND_new(&svr->rand);
00163 fd=skt_connect(svr->hostIP, svr->hostPort,timeout);
00164
00165 if (NULL!=(err=CcsImpl_authInit(fd,svr))) {
00166 fprintf(stderr,"CCS Client error> %s\n",err);
00167 skt_close(fd);
00168 return -1;
00169 }
00170 skt_close(fd);
00171 }
00172
00173
00174 if(CcsSendRequestWithTimeout(svr,"ccs_getinfo",0,0,NULL,timeout) == -1){
00175 fprintf(stderr,"CCS Client Not Alive\n");
00176 return -1;
00177 }
00178
00179
00180 DEBUGF(("Waiting for conv-host to call us back...\n"));
00181
00182 if(CcsRecvResponseMsg(svr,&msg_len,&msg_data,timeout) == -1){
00183 fprintf(stderr,"CCS Client Not Alive\n");
00184 return -1;
00185 }
00186
00187 parseInfo(svr,msg_data);
00188 free(msg_data);
00189
00190 printSvr(svr);
00191 return 0;
00192 }
00193
00194 int CcsNumNodes(CcsServer *svr)
00195 {
00196 return svr->numNodes;
00197 }
00198
00199 int CcsNumPes(CcsServer *svr)
00200 {
00201 return svr->numPes;
00202 }
00203
00204 int CcsNodeFirst(CcsServer *svr, int node)
00205 {
00206 int retval=0,i;
00207 for(i=0;i<node;i++) {
00208 retval += svr->numProcs[node];
00209 }
00210 return retval;
00211 }
00212
00213 int CcsNodeSize(CcsServer *svr,int node)
00214 {
00215 return svr->numProcs[node];
00216 }
00217
00218 int CcsSendRequestGeneric(CcsServer *svr, const char *hdlrID, int pe, int *pes, int size, const void *msg, int timeout) {
00219 const void *bufs[4]; int lens[4]; int nBuffers=0;
00220 CcsMessageHeader hdr;
00221 struct {
00222 unsigned char type[4];
00223 ChMessageInt_t clientID;
00224 ChMessageInt_t replySalt;
00225 SHA1_hash_t hash;
00226 } auth;
00227
00228 hdr.len=ChMessageInt_new(size);
00229 hdr.pe=ChMessageInt_new(pe);
00230 strncpy(hdr.handler,hdlrID,CCS_HANDLERLEN);
00231
00232 if (svr->replyFd!=-1) skt_close(svr->replyFd);
00233
00234
00235 svr->replyFd=skt_connect(svr->hostIP, svr->hostPort,timeout);
00236 if (svr->replyFd==-1) return -1;
00237
00238 if (svr->isAuth==1)
00239 {
00240 auth.type[0]=0x80;
00241 auth.type[1]=0x00;
00242 auth.type[2]=0x00;
00243 auth.type[3]=svr->level;
00244 auth.clientID=ChMessageInt_new(svr->clientID);
00245 svr->replySalt=CCS_RAND_next(&svr->rand);
00246 auth.replySalt=ChMessageInt_new(svr->replySalt);
00247 CCS_AUTH_hash(&svr->key,svr->clientSalt++,
00248 &hdr,&auth.hash);
00249
00250 bufs[nBuffers]=&auth; lens[nBuffers]=sizeof(auth); nBuffers++;
00251 }
00252
00253 bufs[nBuffers]=&hdr; lens[nBuffers]=sizeof(hdr); nBuffers++;
00254
00255
00256 if (pe < -1) {
00257 int i;
00258 ChMessageInt_t *pes_nbo = (ChMessageInt_t *)pes;
00259 for (i=0; i<-pe; ++i) pes_nbo[i] = ChMessageInt_new(pes[i]);
00260 bufs[nBuffers]=pes; lens[nBuffers]=-pe*sizeof(ChMessageInt_t); nBuffers++;
00261 }
00262
00263
00264 if (size>0) {bufs[nBuffers]=msg; lens[nBuffers]=size; nBuffers++;}
00265
00266 if (-1==skt_sendV(svr->replyFd, nBuffers, bufs,lens)) return -1;
00267 DEBUGF(("[%.3f] Request sent\n",CmiWallTimer()));
00268
00269 return 0;
00270 }
00271
00272 int CcsSendRequest(CcsServer *svr, const char *hdlrID, int pe, int size, const void *msg) {
00273 return CcsSendRequestGeneric(svr, hdlrID, pe, NULL, size, msg, 120);
00274 }
00275
00276 int CcsSendRequestWithTimeout(CcsServer *svr, const char *hdlrID, int pe, int size, const void *msg, int timeout) {
00277 return CcsSendRequestGeneric(svr, hdlrID, pe, NULL, size, msg, 120);
00278 }
00279
00280 int CcsSendBroadcastRequest(CcsServer *svr, const char *hdlrID,
00281 int size, const void *msg) {
00282 return CcsSendRequestGeneric(svr, hdlrID, -1, NULL, size, msg, 120);
00283 }
00284
00285 int CcsSendBroadcastRequestWithTimeout(CcsServer *svr, const char *hdlrID,
00286 int size, const void *msg, int timeout) {
00287 return CcsSendRequestGeneric(svr, hdlrID, -1, NULL, size, msg, timeout);
00288 }
00289
00290 int CcsSendMulticastRequest(CcsServer *svr, const char *hdlrID, int npes,
00291 int *pes, int size, const void *msg) {
00292 if (npes < 1) {
00293 fprintf(stderr,"CCS multicast: No processor specified\n");
00294 return -1;
00295 }
00296 if (npes == 1) return CcsSendRequestGeneric(svr, hdlrID, pes[0], NULL, size, msg, 120);
00297 return CcsSendRequestGeneric(svr, hdlrID, -npes, pes, size, msg, 120);
00298 }
00299
00300 int CcsSendMulticastRequestWithTimeout(CcsServer *svr, const char *hdlrID, int npes,
00301 int *pes, int size, const void *msg, int timeout) {
00302 if (npes < 1) {
00303 fprintf(stderr,"CCS multicast: No processor specified\n");
00304 return -1;
00305 }
00306 if (npes == 1) return CcsSendRequestGeneric(svr, hdlrID, pes[0], NULL, size, msg, timeout);
00307 return CcsSendRequestGeneric(svr, hdlrID, -npes, pes, size, msg, timeout);
00308 }
00309
00310
00311 int CcsImpl_recvReplyAuth(CcsServer *svr)
00312 {
00313 SHA1_hash_t hash;
00314 if (!svr->isAuth) return 0;
00315 if (-1==skt_recvN(svr->replyFd,&hash,sizeof(hash))) return -1;
00316 if (CCS_AUTH_differ(&svr->key,svr->replySalt,
00317 NULL,&hash)) return -1;
00318 return 0;
00319 }
00320
00321
00322
00323 int CcsNoResponse(CcsServer *svr)
00324 {
00325 skt_close(svr->replyFd);
00326 svr->replyFd=-1;
00327 return 0;
00328 }
00329
00330
00331
00332 int CcsRecvResponseMsg(CcsServer *svr, int *size,void **newBuf, int timeout)
00333 {
00334 ChMessageInt_t netLen;
00335 unsigned int len;
00336 SOCKET fd=svr->replyFd;
00337 if (-1==CcsImpl_recvReplyAuth(svr)) return -1;
00338 if (1!=skt_select1(fd,1000*timeout)) return -1;
00339 if (-1==skt_recvN(fd,&netLen,sizeof(netLen))) return -1;
00340 *size=len=ChMessageInt(netLen);
00341 *newBuf=malloc(len);
00342 if (-1==skt_recvN(fd,*newBuf,len)) return -1;
00343
00344
00345 skt_close(svr->replyFd);svr->replyFd=-1;
00346 return len;
00347 }
00348
00349
00350
00351 int CcsRecvResponse(CcsServer *svr, int maxsize, void *recvBuffer,int timeout)
00352 {
00353 ChMessageInt_t netLen;
00354 unsigned int len;
00355 SOCKET fd=svr->replyFd;
00356 if (-1==CcsImpl_recvReplyAuth(svr)) return -1;
00357 if (1!=skt_select1(fd,1000*timeout)) return -1;
00358 if (-1==skt_recvN(fd,&netLen,sizeof(netLen))) return -1;
00359 len=ChMessageInt(netLen);
00360 DEBUGF(("[%.3f] recv'd reply length\n",CmiWallTimer()));
00361 if (len>maxsize)
00362 {skt_close(fd);return -1;}
00363 if (-1==skt_recvN(fd,recvBuffer,len)) return -1;
00364
00365
00366 skt_close(svr->replyFd);svr->replyFd=-1;
00367 return len;
00368 }
00369
00370 int CcsProbe(CcsServer *svr)
00371 {
00372 return skt_select1(svr->replyFd,0);
00373 }
00374 int CcsProbeTimeout(CcsServer *svr,int timeoutMs)
00375 {
00376 return skt_select1(svr->replyFd,timeoutMs);
00377 }
00378
00379 void CcsFinalize(CcsServer *svr)
00380 {
00381 if (svr->replyFd!=-1) skt_close(svr->replyFd);
00382 }
00383
00384 #endif
00385
00386
00387