|
Mixe for Privacy and Anonymity in the Internet
|
00001 /* 00002 Copyright (c) 2000, The JAP-Team 00003 All rights reserved. 00004 Redistribution and use in source and binary forms, with or without modification, 00005 are permitted provided that the following conditions are met: 00006 00007 - Redistributions of source code must retain the above copyright notice, 00008 this list of conditions and the following disclaimer. 00009 00010 - Redistributions in binary form must reproduce the above copyright notice, 00011 this list of conditions and the following disclaimer in the documentation and/or 00012 other materials provided with the distribution. 00013 00014 - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors 00015 may be used to endorse or promote products derived from this software without specific 00016 prior written permission. 00017 00018 00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS 00020 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 00021 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS 00022 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00023 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 00024 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 00025 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 00027 */ 00028 00029 00030 #include "StdAfx.h" 00031 #ifdef DYNAMIC_MIX 00032 00033 #include "CADynaNetworking.hpp" 00034 #include "CASocket.hpp" 00035 #include "CASocketAddrINet.hpp" 00036 #include "CAHttpClient.hpp" 00037 #include "CACmdLnOptions.hpp" 00038 #include "CASocketAddr.hpp" 00039 #include "xml/DOM_Output.hpp" 00040 00041 CADynaNetworking::CADynaNetworking() : CAInfoServiceAware() 00042 { 00043 } 00044 00045 CADynaNetworking::~CADynaNetworking() 00046 { 00047 } 00048 00063 SINT32 CADynaNetworking::updateNetworkConfiguration(UINT16 a_port) 00064 { 00065 UINT8 internalIp[255]; 00066 UINT8 externalIp[255]; 00067 UINT32 len = 255; 00068 00069 if( resolveInternalIp( internalIp ) == E_UNKNOWN ) 00070 { 00071 return E_UNKNOWN; 00072 } 00073 if( resolveExternalIp( externalIp, len ) == E_UNKNOWN ) 00074 { 00075 return E_UNKNOWN; 00076 } 00077 00078 // Beware! This resets all information abount ListenerInterfaces! 00079 pglobalOptions->resetNetworkConfiguration(); 00080 00081 DOM_Document doc; 00082 pglobalOptions->getMixXml(doc); 00083 DOM_Element elemRoot = doc.getDocumentElement(); 00084 DOM_Element elemListeners; 00085 getDOMChildByName(elemRoot,(UINT8*)"ListenerInterfaces",elemListeners,false); 00086 if(elemListeners == NULL) 00087 { 00088 elemListeners = doc.createElement("ListenerInterfaces"); 00089 elemRoot.appendChild( elemListeners ); 00090 } 00091 00092 if(strcmp((char*)internalIp, (char*)externalIp) == 0) 00093 { 00094 /* External IP == Internal IP, wonderful */ 00095 createListenerInterface( elemListeners, doc, internalIp, a_port, false, false); 00096 return E_SUCCESS; 00097 } 00098 createListenerInterface( elemListeners, doc, internalIp, a_port, true, false); 00099 createListenerInterface( elemListeners, doc, externalIp, a_port, false, true); 00100 00101 00102 #ifdef DEBUG 00103 UINT8* buff = DOM_Output::dumpToMem(doc,&len); 00104 CAMsg::printMsg(LOG_CRIT, (char*)buff); 00105 #endif 00106 return E_SUCCESS; 00107 } 00108 00121 SINT32 CADynaNetworking::createListenerInterface(DOM_Element r_elemListeners, DOM_Document a_ownerDoc,const UINT8 *a_ip, UINT32 a_port, bool a_bHidden, bool a_bVirtual) 00122 { 00123 DOM_Element elemTmp; 00124 00125 DOM_Element elemListener=a_ownerDoc.createElement("ListenerInterface"); 00126 if( a_bHidden ) 00127 { 00128 elemListener.setAttribute("hidden", "True"); 00129 } 00130 00131 if( a_bVirtual ) 00132 { 00133 elemListener.setAttribute("virtual", "True"); 00134 } 00135 r_elemListeners.appendChild(elemListener); 00136 elemTmp=a_ownerDoc.createElement("Port"); 00137 setDOMElementValue(elemTmp,a_port); 00138 elemListener.appendChild(elemTmp); 00139 elemTmp=a_ownerDoc.createElement("NetworkProtocol"); 00140 setDOMElementValue(elemTmp,(UINT8*)"RAW/TCP"); 00141 elemListener.appendChild(elemTmp); 00142 elemTmp=a_ownerDoc.createElement("IP"); 00143 setDOMElementValue(elemTmp, a_ip); 00144 elemListener.appendChild(elemTmp); 00145 #ifdef DEBUG 00146 UINT32 len; 00147 UINT8* buff = DOM_Output::dumpToMem(elemListener, &len); 00148 CAMsg::printMsg(LOG_CRIT, "%s\n",(char*)buff); 00149 #endif 00150 00151 pglobalOptions->addListenerInterface(elemListener); 00152 return E_SUCCESS; 00153 } 00154 00160 CAListenerInterface *CADynaNetworking::getWorkingListenerInterface() 00161 { 00162 UINT32 interfaces = pglobalOptions->getListenerInterfaceCount(); 00163 CAListenerInterface *pListener = NULL; 00164 for( UINT32 i = 1; i <= interfaces; i++ ) 00165 { 00166 pListener = pglobalOptions->getListenerInterface(i); 00167 if(!pListener->isVirtual()) 00168 break; 00169 delete pListener; 00170 pListener=NULL; 00171 } 00172 return pListener; 00173 } 00174 00180 static THREAD_RETURN ConnectivityLoop(void *p) 00181 { 00182 INIT_STACK; 00183 BEGIN_STACK("CADynaNetworking::ConnectivityLoop"); 00184 00185 CADynaNetworking* parent = (CADynaNetworking*)p; 00186 char buff[1024]; 00187 UINT32 len = 1024; 00188 SINT32 rLen; 00189 char *pechoRequest = NULL; 00190 00191 #ifdef DEBUG 00192 CAMsg::printMsg(LOG_DEBUG, "CADynaNetworking - ConnectivityLoop() started\n"); 00193 #endif 00194 CAListenerInterface *pListener = parent->getWorkingListenerInterface(); 00195 if(pListener == NULL) 00196 { 00197 CAMsg::printMsg(LOG_DEBUG, "CADynaNetworking - ConnectivityLoop - No valid ListenerInterface found, aborting\n"); 00198 THREAD_RETURN_ERROR; 00199 } 00200 00201 CASocket serverSocket; 00202 CASocket socket; 00203 CASocketAddrINet *address = (CASocketAddrINet*)pListener->getAddr(); 00204 if( serverSocket.listen( *address ) != E_SUCCESS ) 00205 { 00206 CAMsg::printMsg(LOG_ERR, "CADynaNetworking - ConnectivityLoop - Unable to listen to standard port, aborting\n"); 00207 goto EXIT; 00208 } 00209 #ifdef DEBUG 00210 CAMsg::printMsg(LOG_ERR, "CADynaNetworking - ConnectivityLoop - Ok, listening...\n"); 00211 #endif 00212 if( serverSocket.accept(socket) != E_SUCCESS) 00213 { 00214 CAMsg::printMsg(LOG_ERR, "CADynaNetworking - ConnectivityLoop - Unable to accept on standard port, aborting\n"); 00215 goto EXIT; 00216 } 00217 #ifdef DEBUG 00218 CAMsg::printMsg(LOG_ERR, "CADynaNetworking - ConnectivityLoop - Ok, i accepted\n"); 00219 #endif 00220 rLen = socket.receive( (UINT8*)buff, len ); 00221 #ifdef DEBUG 00222 CAMsg::printMsg(LOG_DEBUG, "CADynaNetworking - ConnectivityLoop - Received %i Bits: (%s)\n", rLen, buff); 00223 #endif 00224 pechoRequest = new char[rLen+1]; 00225 strncpy(pechoRequest, buff, rLen+1); 00226 #ifdef DEBUG 00227 CAMsg::printMsg(LOG_DEBUG, "CADynaNetworking - ConnectivityLoop - echoRequest: (%s)\n", pechoRequest); 00228 CAMsg::printMsg(LOG_DEBUG, "CADynaNetworking - ConnectivityLoop - Will send: %i chars, %s\n", strlen(pechoRequest), pechoRequest); 00229 00230 #endif 00231 socket.send( (const UINT8*)pechoRequest, rLen); 00232 delete pechoRequest; 00233 pechoRequest = NULL; 00234 EXIT: 00235 FINISH_STACK("CADynaNetworking::ConnectivityLoop"); 00236 00237 delete address; 00238 address = NULL; 00239 socket.close(); 00240 serverSocket.close(); 00241 THREAD_RETURN_SUCCESS; 00242 } 00243 00255 SINT32 CADynaNetworking::verifyConnectivity() 00256 { 00257 SINT32 ret = E_UNKNOWN; 00258 DOM_Element elemRoot; 00259 DOM_Node elemRes; 00260 UINT8 res[255]; 00261 UINT32 len=255; 00262 00263 CAThread* m_pthreadConnectivtyLoop = new CAThread((UINT8*)"ConnectivityThread"); 00264 m_pthreadConnectivtyLoop->setMainLoop(ConnectivityLoop); 00265 // 1, 3+4) 00266 m_pthreadConnectivtyLoop->start(this); 00267 00268 //@todo FIXME We have a race condition here between the sending of the request to the infoservice and our m_pthreadConnectivtyLoop thread listenting 00269 // on the port! 00270 msSleep(1000); 00271 // 2 + 5) 00272 CAListenerInterface *pListener = getWorkingListenerInterface(); 00273 00274 if(pListener == NULL) 00275 { 00276 CAMsg::printMsg( LOG_DEBUG, "Didn't find a useable ListenerInterface, exiting\n"); 00277 // Well, if we can't get a working ListenerInterface, the Thread should't either and return to us 00278 m_pthreadConnectivtyLoop->join(); 00279 return E_UNKNOWN; 00280 } 00281 CASocketAddrINet *addr = (CASocketAddrINet*)pListener->getAddr(); 00282 UINT16 port = addr->getPort(); 00283 delete pListener; 00284 pListener = NULL; 00285 // End Fixme 00286 00287 CASocket tmpSock; 00288 00289 if( sendConnectivityRequest( &elemRoot, port) != E_SUCCESS ) 00290 { 00291 CAMsg::printMsg(LOG_DEBUG, "CADynaNetworking - verifyConnectivity - Unable to query Infoservice for connectivity! This might becomes a problem soon!\n"); 00292 // Release the Thread, maybe it is still blocking in accept 00294 tmpSock.connect(*addr); 00295 tmpSock.close(); 00296 m_pthreadConnectivtyLoop->join(); 00297 goto error; 00298 } 00300 tmpSock.connect(*addr); 00301 tmpSock.close(); 00302 m_pthreadConnectivtyLoop->join(); 00303 00304 if(elemRoot == NULL) 00305 { 00306 CAMsg::printMsg(LOG_ERR, "CADynaNetworking - verifyConnectivity - InfoService answer was not parsable\n"); 00307 goto error; 00308 } 00309 00310 if(getDOMChildByName(elemRoot,(UINT8*)"Result",elemRes)!=E_SUCCESS) 00311 { 00312 CAMsg::printMsg(LOG_ERR, "CADynaNetworking - verifyConnectivity - InfoService answer was not parsable\n"); 00313 goto error; 00314 } 00315 00316 if( getDOMElementValue(elemRes, res, &len) != E_SUCCESS ) 00317 { 00318 CAMsg::printMsg(LOG_ERR, "CADynaNetworking - verifyConnectivity - InfoService answer was not parsable\n"); 00319 goto error; 00320 } 00321 00322 if( strcmp( (const char*)res, "OK" ) == 0) 00323 ret = E_SUCCESS; 00324 error: 00325 delete m_pthreadConnectivtyLoop; 00326 m_pthreadConnectivtyLoop = NULL; 00327 delete addr; 00328 addr = NULL; 00329 return ret; 00330 } 00331 00340 SINT32 CADynaNetworking::sendConnectivityRequest( DOM_Element *r_elemRoot, UINT32 a_port ) 00341 { 00342 DOM_Document doc = DOM_Document::createDocument(); 00343 DOM_Element elemRoot = doc.createElement("ConnectivityCheck"); 00344 doc.appendChild(elemRoot); 00345 DOM_Element elemPort = doc.createElement("Port"); 00346 setDOMElementValue(elemPort,(UINT32)a_port); 00347 elemRoot.appendChild(elemPort); 00348 00349 UINT32 lenOut; 00350 UINT8* buffOut = DOM_Output::dumpToMem(doc,&lenOut); 00351 sendRandomInfoserviceRequest( (UINT8*)"/connectivity", r_elemRoot, buffOut, lenOut); 00352 00353 return E_SUCCESS; 00354 } 00355 00364 SINT32 CADynaNetworking::resolveInternalIp(UINT8* r_ip) 00365 { 00366 struct in_addr in; 00367 struct hostent *hent; 00368 char hostname[256]; 00369 UINT32 internalIp; 00370 if (gethostname(hostname, sizeof(hostname)) < 0) 00371 { 00372 return E_UNKNOWN; 00373 } 00374 /* Maybe we are lucky ;-) */ 00375 in.s_addr=inet_addr(hostname); 00376 if (in.s_addr==INADDR_NONE) 00377 { 00378 hent = (struct hostent *)gethostbyname(hostname); 00379 if(hent) 00380 { 00381 assert(hent->h_length == 4); 00382 memcpy( &in.s_addr, hent->h_addr, hent->h_length ); 00383 00384 if( isInternalIp( ntohl(in.s_addr) ) ) 00385 { 00386 /* Maybe it resolved to 127.0.0.1 or sth., we ask the interface itself*/ 00387 if( getInterfaceIp(&internalIp) == E_SUCCESS) 00388 { 00389 in.s_addr = internalIp; 00390 } 00391 } 00392 } 00393 else 00394 { 00395 if( getInterfaceIp(&internalIp) == E_SUCCESS ) 00396 { 00397 in.s_addr = internalIp; 00398 } 00399 } 00400 } 00401 char* tmp = inet_ntoa(in); 00402 strcpy((char*)r_ip, tmp); 00403 return E_SUCCESS; 00404 } 00405 00415 SINT32 CADynaNetworking::getInterfaceIp(UINT32 *r_addr) 00416 { 00417 CASocket *sock = new CASocket(); 00418 sock->create(); 00419 CASocketAddrINet test; 00420 // FIXME We could use an InfoService here 00421 test.setAddr((const UINT8*)"18.0.0.1", 0); 00422 sock->setSendTimeOut(1); 00423 sock->connect( test ); 00424 sock->getLocalIP(r_addr); 00425 #ifdef DEBUG 00426 in_addr t; 00427 t.s_addr = *r_addr; 00428 CAMsg::printMsg(LOG_DEBUG, "Local IP is: %s\n", inet_ntoa(t)); 00429 #endif 00430 sock->close(); 00431 00432 delete sock; 00433 sock = NULL; 00434 return E_SUCCESS; 00435 } 00436 00445 SINT32 CADynaNetworking::resolveExternalIp(UINT8 *r_ip, UINT32 a_len) 00446 { 00447 UINT8 request[255]; 00448 00449 sprintf((char*) request, "/echoip"); 00450 00451 DOM_Element elemRoot; 00452 if( sendRandomInfoserviceGetRequest(request, &elemRoot) != E_SUCCESS ) 00453 { 00454 CAMsg::printMsg(LOG_DEBUG, "CAInfoService::getPublicIp - Unable to query Infoservice for public IP! This will be a problem soon!\n"); 00455 return E_UNKNOWN; 00456 } 00457 00458 if(elemRoot == NULL) 00459 { 00460 CAMsg::printMsg(LOG_ERR, "CAInfoService::getPublicIp - Answer was not parsable\n"); 00461 return E_UNKNOWN; 00462 } 00463 DOM_Node elemIp; 00464 00465 if(getDOMChildByName(elemRoot,(UINT8*)"IP",elemIp)!=E_SUCCESS) 00466 { 00467 CAMsg::printMsg(LOG_ERR, "CAInfoService::getPublicIp - Answer was not parsable!\n"); 00468 return E_UNKNOWN; 00469 } 00470 00471 if( getDOMElementValue(elemIp, r_ip, &a_len) != E_SUCCESS ) 00472 { 00473 CAMsg::printMsg(LOG_ERR, "CAInfoService::getPublicIp - Answer was not parsable!\n"); 00474 return E_UNKNOWN; 00475 } 00476 00477 CAMsg::printMsg(LOG_DEBUG, "Public IP is: %s\n", (char*)r_ip); 00478 return E_SUCCESS; 00479 } 00480 00481 bool CADynaNetworking::isInternalIp(UINT32 a_ip) 00482 { 00483 if (((a_ip & 0xff000000) == 0x0a000000) || /* 10/8 */ 00484 ((a_ip & 0xff000000) == 0x00000000) || /* 0/8 */ 00485 ((a_ip & 0xff000000) == 0x7f000000) || /* 127/8 */ 00486 ((a_ip & 0xffff0000) == 0xa9fe0000) || /* 169.254/16 */ 00487 ((a_ip & 0xfff00000) == 0xac100000) || /* 172.16/12 */ 00488 ((a_ip & 0xffff0000) == 0xc0a80000)) /* 192.168/16 */ 00489 return true; 00490 return false; 00491 } 00492 00493 #endif //DYNAMIC_MIX
1.7.6.1