summaryrefslogtreecommitdiffstats
path: root/rnprotocol/srvrasmgrcomm.cc
diff options
context:
space:
mode:
Diffstat (limited to 'rnprotocol/srvrasmgrcomm.cc')
-rw-r--r--rnprotocol/srvrasmgrcomm.cc213
1 files changed, 213 insertions, 0 deletions
diff --git a/rnprotocol/srvrasmgrcomm.cc b/rnprotocol/srvrasmgrcomm.cc
new file mode 100644
index 0000000..d977045
--- /dev/null
+++ b/rnprotocol/srvrasmgrcomm.cc
@@ -0,0 +1,213 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/*************************************************************
+ *
+ *
+ * PURPOSE:
+ *
+ *
+ * COMMENTS:
+ * - why sometimes exit() and sometimes return on error?
+ * should be return or exception, always.
+ *
+ ************************************************************/
+
+#include "srvrasmgrcomm.hh"
+#include<stdio.h>
+#include<errno.h>
+#include<stdlib.h>
+#include<unistd.h>
+#include<sys/types.h>
+#include<sys/socket.h>
+#include<netinet/in.h>
+#include<netdb.h>
+#include<iostream>
+#include<string.h>
+#include "raslib/rminit.hh"
+
+
+#include "debug.hh"
+
+
+// exit code of the server when communication is impossible
+// PB: Why 10 ? Anyway, should not use exit in a server, how often did I tell you, Walter Schatz!!!
+const unsigned int EXIT_CODE = 10;
+
+// max number of retries to connect to rasmgr in informRasMgr()
+const unsigned int SRV_MAX_RETRY = 10000000;
+
+// how many retries are attempted before a message is issued informRasMgr()
+const unsigned int SRV_TALK_INTERVAL = 100000;
+
+
+SrvRasmgrComm rasmgrComm;
+
+SrvRasmgrComm::SrvRasmgrComm()
+{
+ timeout = 0;
+ serverName = 0;
+ rasmgrHost = 0;
+ rasmgrPort = -1;
+}
+
+// note: should make use of timeout as defined in cmd line,
+// but that's a major undertaking -- PB 2005-sep-02
+
+void SrvRasmgrComm::init(unsigned int timeOut, const char* instanceName, const char* nRasmgrHost, int nRasmgrPort)
+{
+ timeout = timeOut;
+ serverName = instanceName;
+ rasmgrHost = nRasmgrHost;
+ rasmgrPort = nRasmgrPort;
+}
+
+unsigned int SrvRasmgrComm::getTimeout()
+{
+ return timeout;
+}
+
+void SrvRasmgrComm::informRasmgrServerAvailable()
+{
+ informRasMGR(SERVER_AVAILABLE);
+}
+
+void SrvRasmgrComm::informRasmgrServerDown()
+{
+ informRasMGR(SERVER_DOWN);
+}
+
+void SrvRasmgrComm::informRasmgrServerStillAvailable()
+{
+ // too verbose, blows up log file
+ // RMInit::logOut << "informing rasmgr: server still available." << endl;
+ informRasMGR(SERVER_REGULARSIG);
+}
+
+void SrvRasmgrComm::informRasMGR(int what)
+{ //what: 0 - going down
+ // 1 - available
+ // 2 - regular signal
+
+// cout<<"servername ="<<serverName<<" rasmgrhost="<<rasmgrHost<<" port="<<rasmgrPort<<endl;
+
+// if(what == SERVER_AVAILABLE) accessControl.resetForNewClient();
+
+ struct protoent* getprotoptr = getprotobyname("tcp");
+
+ struct hostent *hostinfo = gethostbyname(rasmgrHost);
+ if(hostinfo==NULL)
+ {
+ RMInit::logOut << "Error: cannot locate rasmgr host '" << rasmgrHost << "': " << strerror(errno) << std::endl;
+ return;
+ }
+
+ sockaddr_in internetSocketAddress;
+ internetSocketAddress.sin_family = AF_INET;
+ internetSocketAddress.sin_port=htons(rasmgrPort);
+ internetSocketAddress.sin_addr=*(struct in_addr*)hostinfo->h_addr;
+
+ int sock;
+
+ bool ok=false;
+ long talkInterval=SRV_TALK_INTERVAL;
+ long maxRetry=SRV_MAX_RETRY;
+ long retry =0;
+ // creating socket
+ for(retry=0;retry<maxRetry;retry++)
+ {
+ sock=socket(PF_INET,SOCK_STREAM,getprotoptr->p_proto);
+ //std::cout<<"Socket="<<sock<<" protocol(tcp)="<<getprotoptr->p_proto<<std::endl;
+
+ if(sock<0)
+ {
+ if( (retry%talkInterval) == 0)
+ {
+ std::cerr<< "Error: server '" << serverName << " cannot open socket to rasmgr (" << retry << " attempts, still retrying): " << strerror(errno) << std::endl;
+ RMInit::logOut << "Error: server '" << serverName << " cannot open socket to rasmgr (" << retry << " attempts, still retrying): " << strerror(errno) << std::endl;
+ }
+ continue;
+ }
+
+ if(connect(sock,(struct sockaddr*)&internetSocketAddress,sizeof(internetSocketAddress)) < 0)
+ {
+ if( (retry%talkInterval) == 0)
+ {
+ std::cerr << "Error: server '" << serverName << " cannot connect to rasmgr (" << retry << " attempts, still retrying): " << strerror(errno) << std::endl;
+ RMInit::logOut << "Error: server '" << serverName << " cannot connect to rasmgr (" << retry << " attempts, still retrying): " << strerror(errno) << std::endl;
+ }
+ close(sock); //yes, some SO requieres this, like DEC from BLVA
+ continue;
+ }
+ ok = true;
+ break;
+ }
+
+ if( !ok )
+ {
+ std::cerr << "Error: unable to contact rasmgr, server '" << serverName << "' herewith giving up." <<std::endl;
+ RMInit::logOut << "Error: unable to contact rasmgr, server '" << serverName << "' herewith giving up." <<std::endl;
+ if(sock)
+ close(sock);
+ exit( EXIT_CODE );
+ }
+
+ // creating the HTTP message
+ char message[200];
+ sprintf(message,"%s%d\r\n\r\n%s %d %ld ","POST rasservernewstatus HTTP/1.1\r\nUserAgent: RasServer/1.0\r\nContent-length: ",strlen(serverName)+3,serverName,what,0);
+
+ // writing message;
+ if(writeWholeMessage(sock,message,strlen(message)+1)<0)
+ {
+ std::cerr << "Error: cannot send message to rasmgr: " << strerror(errno) << std::endl;
+ RMInit::logOut << "Error: cannot send message to rasmgr: " << strerror(errno) << std::endl;
+ close(sock);
+ exit( EXIT_CODE );
+ }
+ close(sock);
+}
+
+
+int SrvRasmgrComm::writeWholeMessage(int socket,char *destBuffer,int buffSize)
+{
+ // we write the whole message, including the ending '\0', which is already in
+ // the buffSize provided by the caller
+ int totalLength=0;
+ int writeNow;
+ while(1)
+ {
+ writeNow = write(socket,destBuffer+totalLength,buffSize-totalLength);
+ if(writeNow == -1)
+ {
+ if(errno == EINTR)
+ continue; // read was interrupted by signal (on bad SO's)
+ return -1; // another error
+ }
+ totalLength+=writeNow;
+
+ if( totalLength==buffSize )
+ break; // THE END
+ }
+
+ return totalLength;
+}
+