00001 #ifndef Impala_Application_SDash_AlertRelay_h
00002 #define Impala_Application_SDash_AlertRelay_h
00003
00004 #include <string>
00005 #include <winsock2.h>
00006 #include <ws2tcpip.h>
00007 #include <stdlib.h>
00008 #include <stdio.h>
00009
00010 #define DEFAULT_TCP_BUFLEN 512
00011
00012 namespace Impala {
00013 namespace Application {
00014 namespace SDash {
00015
00016 class AlertRelay
00017 {
00018
00019 public:
00020
00021 AlertRelay(const std::string& ipAddress = DEFAULT_IP, const std::string& port = DEFAULT_PORT) : mState(-1)
00022 {
00023 mState = Initialize(ipAddress, port);
00024 }
00025
00026 virtual ~AlertRelay()
00027 {
00028 if (IsReady())
00029 {
00030 int result = CloseSockets();
00031 mState = -1;
00032 }
00033 }
00034
00035 bool IsReady()
00036 {
00037 return (mState == 0);
00038 }
00039
00040 int Relay(const std::string& msg)
00041 {
00042 if (!IsReady())
00043 {
00044 printf("AlertRelay not ready; unable to send message: %s", msg);
00045 return 1;
00046 }
00047
00048 std::string completeMsg = "05" + msg;
00049 if (mClientSocket == INVALID_SOCKET)
00050 {
00051
00052
00053
00054
00055
00056
00057 AcceptWithoutBlocking(&mListenSocket, &mClientSocket);
00058 }
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 if (mClientSocket != INVALID_SOCKET)
00079 {
00080 int len = completeMsg.length();
00081 int iSendResult = send( mClientSocket, completeMsg.c_str(), len, 0);
00082 int err = WSAGetLastError();
00083 if (iSendResult == SOCKET_ERROR)
00084 {
00085 printf("send failed: %d\n", err);
00086 printf("Transmission of message failed: %s\n", completeMsg.c_str());
00087 closesocket(mClientSocket);
00088 mClientSocket = INVALID_SOCKET;
00089 return 4;;
00090 }
00091 printf("Message sent: %s\n", completeMsg.c_str());
00092 }
00093 else
00094 printf("Transmission of message skipped: %s\n", completeMsg.c_str());
00095
00096 return 0;
00097 }
00098
00099
00100 private:
00101
00102 static const char* DEFAULT_PORT;
00103 static const char* DEFAULT_IP;
00104
00105 int mState;
00106
00107 SOCKET mListenSocket;
00108 SOCKET mClientSocket;
00109
00110 int Initialize(const std::string& ipAddress, const std::string& port)
00111 {
00112 mListenSocket = SetupListening(ipAddress, port);
00113 if (mListenSocket == INVALID_SOCKET)
00114 {
00115 printf("Setting up listening socket failed failed; unable to relay messages\n");
00116 return 1;
00117 }
00118
00119 mClientSocket = INVALID_SOCKET;
00120
00121 return 0;
00122 }
00123
00124 SOCKET SetupListening(const std::string& ipAddress, const std::string& port)
00125 {
00126 WSADATA wsaData;
00127 SOCKET ListenSocket = INVALID_SOCKET;
00128 struct addrinfo *result = NULL,
00129 hints;
00130
00131
00132 int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
00133 if (iResult != 0) {
00134 printf("WSAStartup failed: %d\n", iResult);
00135 return INVALID_SOCKET;
00136 }
00137
00138 ZeroMemory(&hints, sizeof(hints));
00139 hints.ai_family = AF_INET;
00140 hints.ai_socktype = SOCK_STREAM;
00141 hints.ai_protocol = IPPROTO_TCP;
00142 hints.ai_flags = AI_PASSIVE;
00143
00144
00145 iResult = getaddrinfo(ipAddress.c_str(), port.c_str(), &hints, &result);
00146 if ( iResult != 0 ) {
00147 printf("getaddrinfo failed: %d\n", iResult);
00148 WSACleanup();
00149 return INVALID_SOCKET;
00150 }
00151
00152
00153 ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
00154 if (ListenSocket == INVALID_SOCKET) {
00155 printf("socket failed: %ld\n", WSAGetLastError());
00156 freeaddrinfo(result);
00157 WSACleanup();
00158 return INVALID_SOCKET;
00159 }
00160
00161
00162 iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
00163 if (iResult == SOCKET_ERROR) {
00164 printf("bind failed: %d (error 10049: is the server IP address %s valid?)\n", WSAGetLastError(), ipAddress.c_str());
00165 freeaddrinfo(result);
00166 closesocket(ListenSocket);
00167 WSACleanup();
00168 return INVALID_SOCKET;
00169 }
00170
00171 freeaddrinfo(result);
00172
00173 iResult = listen(ListenSocket, SOMAXCONN);
00174 if (iResult == SOCKET_ERROR) {
00175 printf("listen failed: %d\n", WSAGetLastError());
00176 closesocket(ListenSocket);
00177 WSACleanup();
00178 return INVALID_SOCKET;
00179 }
00180
00181
00182 u_long argp = 1;
00183 int rc = ioctlsocket(ListenSocket, FIONBIO, &argp);
00184
00185
00186 return ListenSocket;
00187 }
00188
00189
00190
00191 int AcceptWithoutBlocking(SOCKET* listenSocket, SOCKET* clientSocket)
00192 {
00193 *clientSocket = accept(*listenSocket, NULL, NULL);
00194 int err = WSAGetLastError();
00195 if (*clientSocket == INVALID_SOCKET)
00196 {
00197 if (err == WSAEWOULDBLOCK)
00198 {
00199 printf("No pending connection requests\n");
00200 }
00201 else
00202 {
00203 printf("accept failed: %d\n", err);
00204 return 1;
00205 }
00206 }
00207
00208 return 0;
00209 }
00210
00211 int CloseSockets()
00212 {
00213
00214 closesocket(mListenSocket);
00215
00216 if (mClientSocket != INVALID_SOCKET)
00217 {
00218
00219 int iResult = shutdown(mClientSocket, SD_SEND);
00220 if (iResult == SOCKET_ERROR) {
00221 printf("shutdown failed: %d\n", WSAGetLastError());
00222 closesocket(mClientSocket);
00223 WSACleanup();
00224 return 1;
00225 }
00226
00227
00228 closesocket(mClientSocket);
00229 }
00230
00231 WSACleanup();
00232 return 0;
00233 }
00234
00235 };
00236
00237 const char* AlertRelay::DEFAULT_IP = "127.0.0.1";
00238 const char* AlertRelay::DEFAULT_PORT = "10000";
00239
00240 }
00241 }
00242 }
00243
00244 #endif