From 456325dc08da1539bf4732d0e0e8118e0d1d41e9 Mon Sep 17 00:00:00 2001 From: drbob Date: Fri, 25 Jan 2008 07:22:15 +0000 Subject: [PATCH] Commit of the new UDP Connection methods and the rewrite of the retroshare core networking stack. This check-in commits the changes to the dht code. An interface to a second new DHT system (OpenDHT) has been added. This has a number of features that make it preferable to the KAD dht network. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@309 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/dht/Makefile | 19 +- libretroshare/src/dht/b64.c | 477 +++++++++++++++++++++++++ libretroshare/src/dht/b64.h | 42 +++ libretroshare/src/dht/dhtclient.h | 68 ++++ libretroshare/src/dht/odhtmgr_test.cc | 143 ++++++++ libretroshare/src/dht/odhtpost_test.cc | 59 +++ libretroshare/src/dht/odhtstr_test.cc | 88 +++++ libretroshare/src/dht/opendht.cc | 456 +++++++++++++++++++++++ libretroshare/src/dht/opendht.h | 80 +++++ libretroshare/src/dht/opendhtmgr.cc | 192 ++++++++++ libretroshare/src/dht/opendhtmgr.h | 64 ++++ libretroshare/src/dht/opendhtstr.cc | 113 ++++++ libretroshare/src/dht/opendhtstr.h | 42 +++ libretroshare/src/dht/servers.txt | 163 +++++++++ 14 files changed, 2004 insertions(+), 2 deletions(-) create mode 100644 libretroshare/src/dht/b64.c create mode 100644 libretroshare/src/dht/b64.h create mode 100644 libretroshare/src/dht/dhtclient.h create mode 100644 libretroshare/src/dht/odhtmgr_test.cc create mode 100644 libretroshare/src/dht/odhtpost_test.cc create mode 100644 libretroshare/src/dht/odhtstr_test.cc create mode 100644 libretroshare/src/dht/opendht.cc create mode 100644 libretroshare/src/dht/opendht.h create mode 100644 libretroshare/src/dht/opendhtmgr.cc create mode 100644 libretroshare/src/dht/opendhtmgr.h create mode 100644 libretroshare/src/dht/opendhtstr.cc create mode 100644 libretroshare/src/dht/opendhtstr.h create mode 100644 libretroshare/src/dht/servers.txt diff --git a/libretroshare/src/dht/Makefile b/libretroshare/src/dht/Makefile index 36cc71947..a5d64daef 100644 --- a/libretroshare/src/dht/Makefile +++ b/libretroshare/src/dht/Makefile @@ -2,17 +2,29 @@ RS_TOP_DIR = .. include ../make.opt -OBJ = dhthandler.o +OBJ = b64.o opendhtstr.o opendht.o opendhtmgr.o + #CADKINC = /home/rmf24/prog/src/KadC #CFLAGS += -I $(CADKINC) #RSLIBS += -L $(CADKINC) -lKadC -all : $(OBJ) librs dhttest +all : $(OBJ) librs odhtstr_test odhtpost_test odhtmgr_test + +#dhttest dhttest: $(OBJ) dhttest.o $(CC) $(CFLAGS) -o dhttest $(OBJ) dhttest.o $(RSLIBS) +odhtpost_test: $(OBJ) odhtpost_test.o + $(CC) $(CFLAGS) -o odhtpost_test $(OBJ) odhtpost_test.o $(RSLIBS) + +odhtstr_test: $(OBJ) odhtstr_test.o + $(CC) $(CFLAGS) -o odhtstr_test $(OBJ) odhtstr_test.o $(RSLIBS) + +odhtmgr_test: $(OBJ) odhtmgr_test.o + $(CC) $(CFLAGS) -o odhtmgr_test $(OBJ) odhtmgr_test.o $(RSLIBS) + librs: $(OBJ) $(AR) r $(LIBRS) $(OBJ) $(RANLIB) $(LIBRS) @@ -20,6 +32,9 @@ librs: $(OBJ) .cc.o: $(CC) $(CFLAGS) -c $< +.c.o: + $(CC) $(CFLAGS) -c $< + clean: -/bin/rm $(OBJ) dhttest.o diff --git a/libretroshare/src/dht/b64.c b/libretroshare/src/dht/b64.c new file mode 100644 index 000000000..f66ba2a0c --- /dev/null +++ b/libretroshare/src/dht/b64.c @@ -0,0 +1,477 @@ +/*********************************************************************\ + +MODULE NAME: b64.c + +AUTHOR: Bob Trower 08/04/01 + +PROJECT: Crypt Data Packaging + +COPYRIGHT: Copyright (c) Trantor Standard Systems Inc., 2001 + +NOTE: This source code may be used as you wish, subject to + the MIT license. See the LICENCE section below. + +DESCRIPTION: + This little utility implements the Base64 + Content-Transfer-Encoding standard described in + RFC1113 (http://www.faqs.org/rfcs/rfc1113.html). + + This is the coding scheme used by MIME to allow + binary data to be transferred by SMTP mail. + + Groups of 3 bytes from a binary stream are coded as + groups of 4 bytes in a text stream. + + The input stream is 'padded' with zeros to create + an input that is an even multiple of 3. + + A special character ('=') is used to denote padding so + that the stream can be decoded back to its exact size. + + Encoded output is formatted in lines which should + be a maximum of 72 characters to conform to the + specification. This program defaults to 72 characters, + but will allow more or less through the use of a + switch. The program enforces a minimum line size + of 4 characters. + + Example encoding: + + The stream 'ABCD' is 32 bits long. It is mapped as + follows: + + ABCD + + A (65) B (66) C (67) D (68) (None) (None) + 01000001 01000010 01000011 01000100 + + 16 (Q) 20 (U) 9 (J) 3 (D) 17 (R) 0 (A) NA (=) NA (=) + 010000 010100 001001 000011 010001 000000 000000 000000 + + + QUJDRA== + + Decoding is the process in reverse. A 'decode' lookup + table has been created to avoid string scans. + +DESIGN GOALS: Specifically: + Code is a stand-alone utility to perform base64 + encoding/decoding. It should be genuinely useful + when the need arises and it meets a need that is + likely to occur for some users. + Code acts as sample code to show the author's + design and coding style. + + Generally: + This program is designed to survive: + Everything you need is in a single source file. + It compiles cleanly using a vanilla ANSI C compiler. + It does its job correctly with a minimum of fuss. + The code is not overly clever, not overly simplistic + and not overly verbose. + Access is 'cut and paste' from a web page. + Terms of use are reasonable. + +VALIDATION: Non-trivial code is never without errors. This + file likely has some problems, since it has only + been tested by the author. It is expected with most + source code that there is a period of 'burn-in' when + problems are identified and corrected. That being + said, it is possible to have 'reasonably correct' + code by following a regime of unit test that covers + the most likely cases and regression testing prior + to release. This has been done with this code and + it has a good probability of performing as expected. + + Unit Test Cases: + + case 0:empty file: + CASE0.DAT -> -> + (Zero length target file created + on both encode and decode.) + + case 1:One input character: + CASE1.DAT A -> QQ== -> A + + case 2:Two input characters: + CASE2.DAT AB -> QUJD -> AB + + case 3:Three input characters: + CASE3.DAT ABC -> QUJD -> ABC + + case 4:Four input characters: + case4.dat ABCD -> QUJDRA== -> ABCD + + case 5:All chars from 0 to ff, linesize set to 50: + + AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIj + JCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZH + SElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWpr + bG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6P + kJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKz + tLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX + 2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7 + /P3+/w== + + case 6:Mime Block from e-mail: + (Data same as test case 5) + + case 7: Large files: + Tested 28 MB file in/out. + + case 8: Random Binary Integrity: + This binary program (b64.exe) was encoded to base64, + back to binary and then executed. + + case 9 Stress: + All files in a working directory encoded/decoded + and compared with file comparison utility to + ensure that multiple runs do not cause problems + such as exhausting file handles, tmp storage, etc. + + ------------- + + Syntax, operation and failure: + All options/switches tested. Performs as + expected. + + case 10: + No Args -- Shows Usage Screen + Return Code 1 (Invalid Syntax) + case 11: + One Arg (invalid) -- Shows Usage Screen + Return Code 1 (Invalid Syntax) + case 12: + One Arg Help (-?) -- Shows detailed Usage Screen. + Return Code 0 (Success -- help request is valid). + case 13: + One Arg Help (-h) -- Shows detailed Usage Screen. + Return Code 0 (Success -- help request is valid). + case 14: + One Arg (valid) -- Uses stdin/stdout (filter) + Return Code 0 (Sucess) + case 15: + Two Args (invalid file) -- shows system error. + Return Code 2 (File Error) + case 16: + Encode non-existent file -- shows system error. + Return Code 2 (File Error) + case 17: + Out of disk space -- shows system error. + Return Code 3 (File I/O Error) + + ------------- + + Compile/Regression test: + gcc compiled binary under Cygwin + Microsoft Visual Studio under Windows 2000 + Microsoft Version 6.0 C under Windows 2000 + +DEPENDENCIES: None + +LICENCE: Copyright (c) 2001 Bob Trower, Trantor Standard Systems Inc. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated + documentation files (the "Software"), to deal in the + Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall + be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY + KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS + OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +VERSION HISTORY: + Bob Trower 08/04/01 -- Create Version 0.00.00B + +\******************************************************************* */ + +#include +#include + +/* +** Translation Table as described in RFC1113 +*/ +static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/* +** Translation Table to decode (created by author) +*/ +static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq"; + +/* +** encodeblock +** +** encode 3 8-bit binary bytes as 4 '6-bit' characters +*/ +void encodeblock( unsigned char in[3], unsigned char out[4], int len ) +{ + out[0] = cb64[ in[0] >> 2 ]; + out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ]; + out[2] = (unsigned char) (len > 1 ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '='); + out[3] = (unsigned char) (len > 2 ? cb64[ in[2] & 0x3f ] : '='); +} + +/* +** decodeblock +** +** decode 4 '6-bit' characters into 3 8-bit binary bytes +*/ +void decodeblock( unsigned char in[4], unsigned char out[3] ) +{ + out[ 0 ] = (unsigned char ) (((in[0] << 2) & 0xff) | ((in[1] >> 4) & 0xff)); + out[ 1 ] = (unsigned char ) (((in[1] << 4) & 0xff) | ((in[2] >> 2) & 0xff)); + out[ 2 ] = (unsigned char ) (((in[2] << 6) & 0xc0) | (in[3] & 0xff)); +} + + +/* mods ... Hacked it up badly ...Robert Fernie (c) */ + +#include +#include +#include +#include +#include "b64.h" + +std::string displayBlock(unsigned char *arr, unsigned int len); + +std::string convertToBase64(std::string input) +{ + unsigned char in[3]; + unsigned char out[4]; + unsigned int len; + + std::string result; + + for(unsigned int i = 0; i < input.length(); i+= 3) + { + len = input.length() - i; + in[0] = input[i]; + if (len > 1) + in[1] = input[i+1]; + else + in[1] = 0; + + if (len > 2) + in[2] = input[i+2]; + else + in[2] = 0; + + + encodeblock(in, out, len); + //std::cerr << "eNcode Block in :" << displayBlock(in, 3); + //std::cerr << "eNcode Block out:" << displayBlock(out, 4); + + for(unsigned int j = 0; j < 4; j++) + { + result += out[j]; + } + } + + return result; +} + +std::string convertFromBase64(std::string input) +{ + unsigned char in[4]; + unsigned char out[3]; + unsigned int len, outlen; + + std::string result; + + for(unsigned int i = 0; i < input.length(); i+= 4) + { + len = input.length() - i; + if (len < 4) + { + /* error */ + std::cerr << "ERROR LENGTH in convertFromBase64"; + std::cerr << std::endl; + return result; + } + outlen = 3; + in[0] = input[i]; + in[1] = input[i+1]; + in[2] = input[i+2]; + in[3] = input[i+3]; + + if (in[3] == '=') + { + outlen--; + } + if (in[2] == '=') + { + outlen--; + } + //std::cerr << "Decode Block in :" << displayBlock(in, 4); + + for(unsigned int j = 0; j < 4; j++) + { + unsigned char v = input[i+j]; + v = (unsigned char) ((v < 43 || v > 122) ? 0 : cd64[ v - 43 ]); + if( v ) { + v = (unsigned char) ((v == '$') ? 0 : v - 61); + } + in[j] = v-1; + } + + decodeblock(in, out); + //std::cerr << "Decode Block out:" << displayBlock(out, 3); + + for(unsigned int j = 0; j < outlen; j++) + { + result += out[j]; + } + } + + return result; +} + + +std::string convertDataToBase64(unsigned char *data, uint32_t dlen) +{ + unsigned char in[3]; + unsigned char out[4]; + unsigned int len; + + std::string result; + + for(unsigned int i = 0; i < dlen; i+= 3) + { + len = dlen - i; + in[0] = data[i]; + if (len > 1) + in[1] = data[i+1]; + else + in[1] = 0; + + if (len > 2) + in[2] = data[i+2]; + else + in[2] = 0; + + + encodeblock(in, out, len); + //std::cerr << "eNcode Block in :" << displayBlock(in, 3); + //std::cerr << "eNcode Block out:" << displayBlock(out, 4); + + for(unsigned int j = 0; j < 4; j++) + { + result += out[j]; + } + } + return result; +} + + +uint32_t DataLenFromBase64(std::string input) +{ + uint32_t len = input.length(); + len = (len / 4) * 3; + /* remove extra char - if '=' */ + if (input[input.length()-1] == '=') + len--; + if (input[input.length()-2] == '=') + len--; + return len; +} + + +bool convertDataFromBase64(std::string input, unsigned char *data, uint32_t *dlen) +{ + unsigned char in[4]; + unsigned char out[3]; + unsigned int len, outlen; + unsigned int offset = 0; + + std::string result; + + len = DataLenFromBase64(input); + if (len > *dlen) + { + std::cerr << "ERROR LENGTH(1) in convertDataFromBase64"; + std::cerr << std::endl; + return false; + } + + for(unsigned int i = 0; i < input.length(); i+= 4) + { + len = input.length() - i; + if (len < 4) + { + /* error */ + std::cerr << "ERROR LENGTH in convertDataFromBase64"; + std::cerr << std::endl; + return false; + } + outlen = 3; + in[0] = input[i]; + in[1] = input[i+1]; + in[2] = input[i+2]; + in[3] = input[i+3]; + + if (in[3] == '=') + { + outlen--; + } + if (in[2] == '=') + { + outlen--; + } + //std::cerr << "Decode Block in :" << displayBlock(in, 4); + + for(unsigned int j = 0; j < 4; j++) + { + unsigned char v = input[i+j]; + v = (unsigned char) ((v < 43 || v > 122) ? 0 : cd64[ v - 43 ]); + if( v ) { + v = (unsigned char) ((v == '$') ? 0 : v - 61); + } + in[j] = v-1; + } + + decodeblock(in, out); + //std::cerr << "Decode Block out:" << displayBlock(out, 3); + + for(unsigned int j = 0; j < outlen; j++) + { + data[offset++] = out[j]; + } + } + + *dlen = offset; + return true; +} + + + + +std::string displayBlock(unsigned char *arr, unsigned int len) +{ + std::ostringstream out; + + for(unsigned int j = 0; j < len; j++) + { + out << std::hex << (int) arr[j] << "[" << arr[j] << "] "; + } + out << std::endl; + return out.str(); +} + + + + + + diff --git a/libretroshare/src/dht/b64.h b/libretroshare/src/dht/b64.h new file mode 100644 index 000000000..9697adf4a --- /dev/null +++ b/libretroshare/src/dht/b64.h @@ -0,0 +1,42 @@ +/* + * libretroshare/src/dht: b64.h + * + * Interface with OpenDHT for RetroShare. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + + +#ifndef BASE64_CODE_H +#define BASE64_CODE_H + +#include + +std::string convertToBase64(std::string input); +std::string convertFromBase64(std::string input); + + +uint32_t DataLenFromBase64(std::string input); +std::string convertDataToBase64(unsigned char *data, uint32_t dlen); +bool convertDataFromBase64(std::string input, unsigned char *data, uint32_t *dlen); + + +#endif + diff --git a/libretroshare/src/dht/dhtclient.h b/libretroshare/src/dht/dhtclient.h new file mode 100644 index 000000000..b4c3411db --- /dev/null +++ b/libretroshare/src/dht/dhtclient.h @@ -0,0 +1,68 @@ +/* + * libretroshare/src/dht: dhtclient.h + * + * Interface with DHT Client for RetroShare. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#ifndef RS_GENERIC_DHT_CLIENT_H +#define RS_GENERIC_DHT_CLIENT_H + +#include +#include +#include + +class DHTClient +{ + public: + + /* initialise from file */ +virtual bool loadServers(std::string filename) = 0; + + /* check that its working */ +virtual bool dhtActive() = 0; + + /* publish / search */ +virtual bool publishKey(std::string key, std::string value, uint32_t ttl) = 0; +virtual bool searchKey(std::string key, std::list &values) = 0; + +}; + + +class DHTClientDummy: public DHTClient +{ + public: + + /* initialise from file */ +virtual bool loadServers(std::string filename) { return true; } + + /* check that its working */ +virtual bool dhtActive() { return true; } + + /* publish / search */ +virtual bool publishKey(std::string key, std::string value, uint32_t ttl) { return true; } +virtual bool searchKey(std::string key, std::list &values) { return true; } + +}; + + +#endif + diff --git a/libretroshare/src/dht/odhtmgr_test.cc b/libretroshare/src/dht/odhtmgr_test.cc new file mode 100644 index 000000000..66a11ddeb --- /dev/null +++ b/libretroshare/src/dht/odhtmgr_test.cc @@ -0,0 +1,143 @@ +/* + * libretroshare/src/dht: odhtmgr_test.cc + * + * Interface with OpenDHT for RetroShare. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + + + +/***** Test for the new DHT system *****/ + + +#include "util/rsnet.h" +#include "util/rsthreads.h" +#include "util/rsprint.h" + +#include "pqi/p3dhtmgr.h" +#include "pqi/pqimonitor.h" +#include "dht/opendhtmgr.h" + +#include +#include + +void usage(char *name) +{ + std::cerr << "USAGE: " << name << " -o OwnId [ -p PeerId1 [ -p PeerId2 [ ... ] ] ] "; + std::cerr << std::endl; + exit(1); +} + +int main(int argc, char **argv) +{ + int c; + bool setOwnId = false; + std::string ownId; + std::list peerIds; + + while(-1 != (c = getopt(argc, argv, "o:p:"))) + { + switch (c) + { + case 'o': + ownId = optarg; + setOwnId = true; + break; + case 'p': + peerIds.push_back(std::string(optarg)); + break; + default: + usage(argv[0]); + break; + } + } + + if (!setOwnId) + { + std::cerr << "Missing OwnId!"; + usage(argv[0]); + } + + bool haveOwnAddress = false; + time_t startTime = time(NULL); + + pqiConnectCbDummy cbTester; + OpenDHTMgr dhtTester(ownId, &cbTester); + + /* startup dht */ + std::cerr << "Starting up DhtTester()" << std::endl; + dhtTester.start(); + + /* wait for a little before switching on */ + sleep(1); + + std::cerr << "Switching on DhtTester()" << std::endl; + dhtTester.setDhtOn(true); + + std::cerr << "Adding a List of Peers" << std::endl; + std::list::iterator it; + for(it = peerIds.begin(); it != peerIds.end(); it++) + { + dhtTester.findPeer(*it); + } + + + /* wait loop */ + while(1) + { + std::cerr << "Main waiting..." << std::endl; + sleep(3); + + if (!haveOwnAddress) + { + if (time(NULL) - startTime > 20) + { + std::cerr << "Setting Own Address!" << std::endl; + haveOwnAddress = true; + + uint32_t type = DHT_ADDR_UDP; + + struct sockaddr_in laddr; + inet_aton("10.0.0.111", &(laddr.sin_addr)); + laddr.sin_port = htons(7812); + laddr.sin_family = AF_INET; + + struct sockaddr_in raddr; + inet_aton("10.0.0.11", &(raddr.sin_addr)); + raddr.sin_port = htons(7812); + raddr.sin_family = AF_INET; + + dhtTester.setExternalInterface(laddr, raddr, type); + } + } + + } +}; + + + + + + + + + + diff --git a/libretroshare/src/dht/odhtpost_test.cc b/libretroshare/src/dht/odhtpost_test.cc new file mode 100644 index 000000000..359545d4a --- /dev/null +++ b/libretroshare/src/dht/odhtpost_test.cc @@ -0,0 +1,59 @@ +/* + * libretroshare/src/dht: odhtport_test.cc + * + * Interface with OpenDHT for RetroShare. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + + +#include "opendht.h" +#include "util/rsprint.h" + +#include + +int main() +{ + std::string agent = "Hand-Crafted Thread"; + std::string keyIn = "color"; + //std::string value = "aaaaBBBBccccDDDDe"; + std::string value = "1234567890aaaaBBBBccccDDDDe"; + //std::string value = "12345678901234567890aaaaBBBBccccDDDDe"; + //std::string value = "aaa12345678901234567890aaaaBBBBccccDDDDe"; + uint32_t ttl = 600; + std::string client= "Retroshare v0.4"; + uint32_t maxresp= 1024; + + std::string key = RsUtil::HashId(keyIn, false); + + OpenDHTClient dht; + dht.loadServers("./servers.txt"); + + dht.publishKey(key, value, ttl); + + sleep(10); + + std::list values; + dht.searchKey(key, values); + + + return 1; +} + diff --git a/libretroshare/src/dht/odhtstr_test.cc b/libretroshare/src/dht/odhtstr_test.cc new file mode 100644 index 000000000..bffa6d309 --- /dev/null +++ b/libretroshare/src/dht/odhtstr_test.cc @@ -0,0 +1,88 @@ +/* + * libretroshare/src/dht: odhtstr_test.cc + * + * Interface with OpenDHT for RetroShare. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "opendhtstr.h" +#include "b64.h" +#include + +int main() +{ + + std::string host = "abc.bgg.trer.dgg"; + uint16_t port = 9242; + + std::string agent = "Hand-Crafted Thread"; + std::string key = "BigKey"; + std::string value = "96324623924"; + uint32_t ttl = 600; + std::string client= "Retroshare v0.4"; + uint32_t maxresp= 1024; + + /* some encodings */ + std::string i1 = "color"; + std::string i2 = "green"; + std::string i3 = "blue"; + std::string i4 = "abdflhdffjadlgfal12=345=="; + + std::string o1 = convertToBase64(i1); + std::string o2 = convertToBase64(i2); + std::string o3 = convertToBase64(i3); + std::string o4 = convertToBase64(i4); + std::string o5 = "bdD+gAEUW+xKEtDiLacRxJcNAAs="; + + std::cerr << "In:" << i1 << " encoded:" << o1 << " decoded:" << convertFromBase64(o1); + std::cerr << std::endl; + std::cerr << "In:" << i2 << " encoded:" << o2 << " decoded:" << convertFromBase64(o2); + std::cerr << std::endl; + std::cerr << "In:" << i3 << " encoded:" << o3 << " decoded:" << convertFromBase64(o3); + std::cerr << std::endl; + std::cerr << "In:" << i4 << " encoded:" << o4 << " decoded:" << convertFromBase64(o4); + std::cerr << std::endl; + std::cerr << "Encoded:" << o5 << " decoded:" << convertFromBase64(o5); + std::cerr << std::endl; + + + /* create some strings */ + + std::string req1 = createOpenDHT_put(key, value, ttl, client); + std::string req2 = createOpenDHT_get(key, maxresp, client); + + std::string putheader = createHttpHeader(host, port, agent, req1.length()); + std::string getheader = createHttpHeader(host, port, agent, req2.length()); + + std::string putreq = putheader + req1; + std::string getreq = getheader + req2; + + + std::cerr << "Example Put Request is:" << std::endl; + std::cerr << putreq << std::endl; + + std::cerr << "Example Get Request is:" << std::endl; + std::cerr << getreq << std::endl; + + return 1; +} + + diff --git a/libretroshare/src/dht/opendht.cc b/libretroshare/src/dht/opendht.cc new file mode 100644 index 000000000..96d5c1886 --- /dev/null +++ b/libretroshare/src/dht/opendht.cc @@ -0,0 +1,456 @@ +/* + * libretroshare/src/dht: opendht.cc + * + * Interface with OpenDHT for RetroShare. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "dht/opendht.h" +#include "dht/opendhtstr.h" +#include "dht/b64.h" +#include + +const std::string openDHT_Client = "Retroshare V0.4"; +const std::string openDHT_Agent = "RS-HTTP-V0.4"; + +#define MAX_DHT_PEER_FAILS 5 +#define MAX_DHT_TOTAL_FAILS 5 +#define MAX_DHT_ATTEMPTS 5 +#define MIN_DHT_SERVERS 5 + +#define OPENDHT_DEBUG 1 + +bool OpenDHTClient::loadServers(std::string filename) +{ + /* open the file */ + std::ifstream file(filename.c_str()); + + /* chew first line */ + file.ignore(1024, '\n'); + + std::string line; + char number[1024]; + char ipaddr[1024]; + char dnsname[1024]; + + dhtMutex.lock(); /**** LOCK ****/ + mServers.clear(); + dhtMutex.unlock(); /**** UNLOCK ****/ + + while((!file.eof()) && (!file.fail())) + { + line = ""; + getline(file, line); + + if (3 == sscanf(line.c_str(), "%1023s %1023s %1023s", number, ipaddr, dnsname)) + { + dhtServer srv; + srv.host = dnsname; + srv.port = 5851; + srv.failed = 0; + srv.ts = 0; + srv.addr.sin_addr.s_addr = 0; + srv.addr.sin_port = 0; + +#ifdef OPENDHT_DEBUG + std::cerr << "Read Server: " << dnsname << std::endl; +#endif + + dhtMutex.lock(); /**** LOCK ****/ + mServers[dnsname] = srv; + dhtMutex.unlock(); /**** UNLOCK ****/ + + } + else + { + +#ifdef OPENDHT_DEBUG + std::cerr << "Failed to Read Server" << std::endl; +#endif + } + + dhtMutex.lock(); /**** LOCK ****/ + mDHTFailCount = 0; + dhtMutex.unlock(); /**** UNLOCK ****/ + } + + return true; +} + + +bool OpenDHTClient::getServer(std::string &host, uint16_t &port, struct sockaddr_in &addr) +{ + /* randomly choose one */ + dhtMutex.lock(); /**** LOCK ****/ + + uint32_t len = mServers.size(); + uint32_t rnd = len * (rand() / (RAND_MAX + 1.0)); + + if (len < 1) + { +#ifdef OPENDHT_DEBUG + std::cerr << "OpenDHTClient::getServer() No Servers available!" << std::endl; +#endif + dhtMutex.unlock(); /**** UNLOCK ****/ + return false; + } + + std::map::const_iterator it; + uint32_t i = 0; + for(it = mServers.begin(); (it != mServers.end()) && (i < rnd); it++, i++); + + if (it == mServers.end()) + { +#ifdef OPENDHT_DEBUG + std::cerr << "OpenDHTClient::getServer() Error getting Server!" << std::endl; +#endif + dhtMutex.unlock(); /**** UNLOCK ****/ + return false; + } + + host = (it->second).host; + port = (it->second).port; + + time_t now = time(NULL); + + if (now - (it->second).ts < 3600) + { + addr = (it->second).addr; + } + else + { + addr.sin_addr.s_addr = 0; + } + + dhtMutex.unlock(); /**** UNLOCK ****/ + + return true; +} + + +bool OpenDHTClient::setServerIp(std::string host, struct sockaddr_in addr) +{ + dhtMutex.lock(); /**** LOCK ****/ + + std::map::iterator it; + it = mServers.find(host); + if (it == mServers.end()) + { + dhtMutex.unlock(); /**** UNLOCK ****/ +#ifdef OPENDHT_DEBUG + std::cerr << "OpenDHTClient::setServerIp() Error finding Server!" << std::endl; +#endif + return false; + } + + (it -> second).addr = addr; + (it -> second).ts = time(NULL); + (it -> second).failed = 0; + + mDHTFailCount = 0; + + dhtMutex.unlock(); /**** UNLOCK ****/ + + return true; +} + + +void OpenDHTClient::setServerFailed(std::string host) +{ + dhtMutex.lock(); /**** LOCK ****/ + + std::map::iterator it; + it = mServers.find(host); + if (it == mServers.end()) + { +#ifdef OPENDHT_DEBUG + std::cerr << "OpenDHTClient::setServerFailed() Error finding Server!" << std::endl; +#endif + dhtMutex.unlock(); /**** UNLOCK ****/ + return; + } + + mDHTFailCount++; + if (mDHTFailCount > MAX_DHT_TOTAL_FAILS) /* might be not connected to Internet */ + { +#ifdef OPENDHT_DEBUG + std::cerr << "OpenDHTClient::setServerFailed() Probably not connected!" << std::endl; +#endif + dhtMutex.unlock(); /**** UNLOCK ****/ + return; + } + + /* up the fail count on this one */ + (it -> second).failed++; + + if ((it -> second).failed > MAX_DHT_PEER_FAILS) + { +#ifdef OPENDHT_DEBUG + std::cerr << "OpenDHTClient::setServerFailed() fail count high -> removing: "; + std::cerr << host << " from list" << std::endl; +#endif + /* remove from list */ + mServers.erase(it); + } + + dhtMutex.unlock(); /**** UNLOCK ****/ + return; +} + +bool OpenDHTClient::dhtActive() +{ + dhtMutex.lock(); /**** LOCK ****/ + + bool ok = (mDHTFailCount <= MAX_DHT_TOTAL_FAILS) && + (mServers.size() > MIN_DHT_SERVERS); + + dhtMutex.unlock(); /**** UNLOCK ****/ + + return ok; +} + +bool OpenDHTClient::publishKey(std::string key, std::string value, uint32_t ttl) +{ + /* create request */ + std::string putmsg = createOpenDHT_put(key, value, ttl, openDHT_Client); + std::string response; + + for(uint16_t i = 0; (!openDHT_sendMessage(putmsg, response)); i++) + { + if (i > MAX_DHT_ATTEMPTS) + { +#ifdef OPENDHT_DEBUG + std::cerr << "OpenDHTClient::openDHT_publishKey() Failed -> Giving Up"; + std::cerr << std::endl; +#endif + return false; + } + +#ifdef OPENDHT_DEBUG + std::cerr << "OpenDHTClient::openDHT_publishKey() Failed -> reattempting"; + std::cerr << std::endl; +#endif + } + + /* check response */ + return true; +} + + +bool OpenDHTClient::searchKey(std::string key, std::list &values) +{ + /* create request */ + std::string getmsg = createOpenDHT_get(key, 1024, openDHT_Client); + std::string response; + + for(uint16_t i = 0; (!openDHT_sendMessage(getmsg, response)); i++) + { + if (i > MAX_DHT_ATTEMPTS) + { +#ifdef OPENDHT_DEBUG + std::cerr << "OpenDHTClient::openDHT_searchKey() Failed -> Giving Up"; + std::cerr << std::endl; +#endif + return false; + } +#ifdef OPENDHT_DEBUG + std::cerr << "OpenDHTClient::openDHT_searchKey() Failed -> reattempting"; + std::cerr << std::endl; +#endif + } + + + /* search through the response for ... */ + + uint32_t start = 0; + uint32_t loc = 0; + uint32_t end = 0; + + while(1) + { + loc = response.find("", start); + if (loc == std::string::npos) + return true; /* finished */ + loc += 8; /* shift to end of */ + + end = response.find("", loc); + if (end == std::string::npos) + return true; /* finished */ + + std::string value = response.substr(loc, end-loc); + + /* clear out whitespace */ + for(uint32_t i = 0; i < value.length();) + { + if (isspace(value[i])) + { + value.erase(i,1); + std::cerr << "Cleanup Result:" << value << ":END:" << std::endl; + } + else + { + i++; + } + } + + if (value.length() > 0) + { + std::cerr << "openDHT_searchKey() Value:" << value << ":END:" << std::endl; + std::string result = convertFromBase64(value); + std::cerr << "openDHT_searchKey() Result:" << result << ":END:" << std::endl; + values.push_back(result); + } + + /* the answer should be between loc and end */ + start = end + 9; + } + + /* parse response */ + return true; +} + + +bool OpenDHTClient::openDHT_sendMessage(std::string msg, std::string &response) +{ + struct sockaddr_in addr; + std::string host; + uint16_t port; + + if (!getServer(host, port, addr)) + { +#ifdef OPENDHT_DEBUG + std::cerr << "OpenDHTClient::openDHT_sendMessage() Failed to get Server"; + std::cerr << std::endl; +#endif + return false; + } + + if (addr.sin_addr.s_addr == 0) + { + /* lookup the address */ + addr.sin_port = htons(port); + if (LookupDNSAddr(host, addr) && + (addr.sin_addr.s_addr != 0)) + { + /* update the IP addr if necessary */ + setServerIp(host, addr); + } + else + { + /* no address */ + std::cerr << "OpenDHTClient::openDHT_sendMessage()"; + std::cerr << " ERROR: No Address"; + std::cerr << std::endl; + setServerFailed(host); + + return false; + } + } + + std::cerr << "OpenDHTClient::openDHT_sendMessage()"; + std::cerr << " Connecting to:" << host << ":" << port; + std::cerr << " (" << inet_ntoa(addr.sin_addr) << ":" << ntohs(addr.sin_port) << ")"; + std::cerr << std::endl; + + /* create request */ + std::string putheader = createHttpHeader(host, port, openDHT_Agent, msg.length()); + + /* open a socket */ + int sockfd = unix_socket(PF_INET, SOCK_STREAM, 0); + + /* connect */ + int err = unix_connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)); + if (err) + { + unix_close(sockfd); + std::cerr << "OpenDHTClient::openDHT_sendMessage()"; + std::cerr << " ERROR: Failed to Connect"; + std::cerr << std::endl; + + setServerFailed(host); + + return false; + } + + std::cerr << "HTTP message *******************" << std::endl; + std::cerr << putheader; + std::cerr << msg; + std::cerr << std::endl; + std::cerr << "HTTP message *******************" << std::endl; + + /* send data */ + int sendsize = strlen(putheader.c_str()); + int size = send(sockfd, putheader.c_str(), sendsize, 0); + if (sendsize != size) + { + unix_close(sockfd); + std::cerr << "OpenDHTClient::openDHT_sendMessage()"; + std::cerr << " ERROR: Failed to Send(1)"; + std::cerr << std::endl; + + setServerFailed(host); + + return false; + } + std::cerr << "OpenDHTClient::openDHT_sendMessage()"; + std::cerr << " Send(1):" << size; + std::cerr << std::endl; + + sendsize = strlen(msg.c_str()); + size = send(sockfd, msg.c_str(), sendsize, 0); + if (sendsize != size) + { + unix_close(sockfd); + std::cerr << "OpenDHTClient::openDHT_sendMessage()"; + std::cerr << " ERROR: Failed to Send(2)"; + std::cerr << std::endl; + + setServerFailed(host); + + return false; + } + + std::cerr << "OpenDHTClient::openDHT_sendMessage()"; + std::cerr << " Send(2):" << size; + std::cerr << std::endl; + + /* now wait for the response */ + sleep(1); + + int recvsize = 10240; /* 10kb */ + void *inbuf = malloc(recvsize); + size = recv(sockfd, inbuf, recvsize, 0); + + response = (char *) inbuf; + free(inbuf); + + /* print it out */ + std::cerr << "HTTP response *******************" << std::endl; + std::cerr << response; + std::cerr << std::endl; + std::cerr << "HTTP response *******************" << std::endl; + + close(sockfd); + + return true; +} + + diff --git a/libretroshare/src/dht/opendht.h b/libretroshare/src/dht/opendht.h new file mode 100644 index 000000000..b8a80dad6 --- /dev/null +++ b/libretroshare/src/dht/opendht.h @@ -0,0 +1,80 @@ +/* + * libretroshare/src/dht: opendht.h + * + * Interface with OpenDHT for RetroShare. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#ifndef RS_OPEN_DHT_CLIENT_H +#define RS_OPEN_DHT_CLIENT_H + +#include "pqi/pqinetwork.h" +#include "util/rsthreads.h" + +#include +#include +#include +#include + +#include "dht/dhtclient.h" + +class dhtServer +{ + public: + + std::string host; + uint16_t port; + uint16_t failed; + time_t ts; + struct sockaddr_in addr; +}; + +class OpenDHTClient: public DHTClient +{ + public: + +virtual bool publishKey(std::string key, std::string value, uint32_t ttl); +virtual bool searchKey(std::string key, std::list &values); + + /* Fns accessing data */ +virtual bool loadServers(std::string filename); +virtual bool dhtActive(); + + private: +bool getServer(std::string &host, uint16_t &port, struct sockaddr_in &addr); +bool setServerIp(std::string host, struct sockaddr_in addr); +void setServerFailed(std::string host); + + private: + + /* generic send msg */ + bool openDHT_sendMessage(std::string msg, std::string &response); + + RsMutex dhtMutex; + std::map mServers; + uint32_t mDHTFailCount; + +}; + + +#endif + + diff --git a/libretroshare/src/dht/opendhtmgr.cc b/libretroshare/src/dht/opendhtmgr.cc new file mode 100644 index 000000000..13850873d --- /dev/null +++ b/libretroshare/src/dht/opendhtmgr.cc @@ -0,0 +1,192 @@ +/* + * libretroshare/src/dht: opendhtmgr.cc + * + * Interface with OpenDHT for RetroShare. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "dht/opendhtmgr.h" +#include "dht/opendht.h" +#include "util/rsthreads.h" /* for pthreads headers */ + + +class dhtSearchData +{ + public: + OpenDHTMgr *mgr; + DHTClient *client; + std::string key; +}; + + +class dhtPublishData +{ + public: + OpenDHTMgr *mgr; + DHTClient *client; + std::string key; + std::string value; + uint32_t ttl; +}; + +/* Thread routines */ + +extern "C" void* doDhtPublish(void* p) +{ + dhtPublishData *data = (dhtPublishData *) p; + if ((!data) || (!data->mgr) || (!data->client)) + { + pthread_exit(NULL); + } + + /* publish it! */ + data->client->publishKey(data->key, data->value, data->ttl); + + delete data; + pthread_exit(NULL); +} + + +extern "C" void* doDhtSearch(void* p) +{ + dhtSearchData *data = (dhtSearchData *) p; + if ((!data) || (!data->mgr) || (!data->client)) + { + pthread_exit(NULL); + } + + /* search it! */ + std::list values; + + if (data->client->searchKey(data->key, values)) + { + /* callback */ + std::list::iterator it; + for(it = values.begin(); it != values.end(); it++) + { + data->mgr->resultDHT(data->key, *it); + } + } + + delete data; + pthread_exit(NULL); +} + + + + +OpenDHTMgr::OpenDHTMgr(std::string ownId, pqiConnectCb* cb) + :p3DhtMgr(ownId, cb) +{ + return; +} + + + /********** OVERLOADED FROM p3DhtMgr ***************/ +bool OpenDHTMgr::init() +{ + std::string configpath = "."; + + /* load up DHT gateways */ + //mClient = new OpenDHTClient(); + mClient = new DHTClientDummy(); + + std::string filename = configpath; + if (configpath.size() > 0) + { + filename += "/"; + } + filename += "servers.txt"; + + return mClient -> loadServers(filename); +} + +bool OpenDHTMgr::shutdown() +{ + /* do nothing */ + if (mClient) + { + delete mClient; + mClient = NULL; + return true; + } + + return false; +} + +bool OpenDHTMgr::dhtActive() +{ + /* do nothing */ + if ((mClient) && (mClient -> dhtActive())) + { + return true; + } + return false; +} + +int OpenDHTMgr::status(std::ostream &out) +{ + /* do nothing */ + return 1; +} + + +/* Blocking calls (only from thread) */ +bool OpenDHTMgr::publishDHT(std::string key, std::string value, uint32_t ttl) +{ + /* launch a publishThread */ + pthread_t tid; + + dhtPublishData *pub = new dhtPublishData; + pub->mgr = this; + pub->client = mClient; + pub->key = key; + pub->value = value; + pub->ttl = ttl; + + void *data = (void *) pub; + pthread_create(&tid, 0, &doDhtPublish, data); + + return true; +} + +bool OpenDHTMgr::searchDHT(std::string key) +{ + /* launch a publishThread */ + pthread_t tid; + + dhtSearchData *dht = new dhtSearchData; + dht->mgr = this; + dht->client = mClient; + dht->key = key; + + void *data = (void *) dht; + pthread_create(&tid, 0, &doDhtSearch, data); + + return true; +} + + /********** OVERLOADED FROM p3DhtMgr ***************/ + + + + + diff --git a/libretroshare/src/dht/opendhtmgr.h b/libretroshare/src/dht/opendhtmgr.h new file mode 100644 index 000000000..93b6a24ca --- /dev/null +++ b/libretroshare/src/dht/opendhtmgr.h @@ -0,0 +1,64 @@ +/* + * libretroshare/src/dht: opendhtmgr.h + * + * Interface with OpenDHT for RetroShare. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#ifndef RS_OPEN_DHT_MGR_H +#define RS_OPEN_DHT_MGR_H + +#include "pqi/p3dhtmgr.h" +#include "dht/dhtclient.h" + +#include +#include +#include + +class OpenDHTMgr: public p3DhtMgr +{ + public: + + OpenDHTMgr(std::string ownId, pqiConnectCb* cb); + + protected: + + /********** OVERLOADED FROM p3DhtMgr ***************/ +virtual bool init(); +virtual bool shutdown(); +virtual bool dhtActive(); +virtual int status(std::ostream &out); + +/* Blocking calls (only from thread) */ +virtual bool publishDHT(std::string key, std::string value, uint32_t ttl); +virtual bool searchDHT(std::string key); + + /********** OVERLOADED FROM p3DhtMgr ***************/ + + private: + + DHTClient *mClient; +}; + + +#endif + + diff --git a/libretroshare/src/dht/opendhtstr.cc b/libretroshare/src/dht/opendhtstr.cc new file mode 100644 index 000000000..479f18aa9 --- /dev/null +++ b/libretroshare/src/dht/opendhtstr.cc @@ -0,0 +1,113 @@ +/* + * libretroshare/src/dht: opendhtstr.cc + * + * Interface with OpenDHT for RetroShare. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include +#include + +#include "opendhtstr.h" +#include "b64.h" + +std::string createHttpHeader(std::string host, uint16_t port, std::string agent, uint32_t length) +{ + std::ostringstream req; + + req << "POST / HTTP/1.0\r\n"; + req << "Host: " << host << ":" << port << "\r\n"; + req << "User-Agent: " << agent << "\r\n"; + req << "Content-Type: text/xml\r\n"; + req << "Content-Length: " << length << "\r\n"; + req << "\r\n"; + + return req.str(); +}; + +std::string createOpenDHT_put(std::string key, std::string value, uint32_t ttl, std::string client) +{ + std::ostringstream req; + + req << "" << std::endl; + req << "" << std::endl; + req << "\tput" << std::endl; + req << "\t" << std::endl; + + req << "\t\t"; + req << convertToBase64(key); + req << "" << std::endl; + + req << "\t\t"; + req << convertToBase64(value); + req << "" << std::endl; + + req << "\t\t"; + req << ttl; + req << "" << std::endl; + + req << "\t\t"; + req << client; + req << "" << std::endl; + + req << "\t" << std::endl; + req << "" << std::endl; + + return req.str(); +} + + +std::string createOpenDHT_get(std::string key, uint32_t maxresponse, std::string client) +{ + std::ostringstream req; + + req << "" << std::endl; + req << "" << std::endl; + req << "\tget" << std::endl; + req << "\t" << std::endl; + + /* key */ + req << "\t\t"; + req << convertToBase64(key); + req << "" << std::endl; + + /* max response */ + req << "\t\t"; + req << maxresponse; + req << "" << std::endl; + + /* placemark (NULL) */ + req << "\t\t"; + req << "" << std::endl; + + req << "\t\t"; + req << client; + req << "" << std::endl; + + req << "\t" << std::endl; + req << "" << std::endl; + + return req.str(); +} + + + + diff --git a/libretroshare/src/dht/opendhtstr.h b/libretroshare/src/dht/opendhtstr.h new file mode 100644 index 000000000..c43404608 --- /dev/null +++ b/libretroshare/src/dht/opendhtstr.h @@ -0,0 +1,42 @@ +/* + * libretroshare/src/dht: opendhtstr.h + * + * Interface with OpenDHT for RetroShare. + * + * Copyright 2007-2008 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#ifndef OPENDHT_STRING_CODE_H +#define OPENDHT_STRING_CODE_H + +#include +#include + +std::string createHttpHeader(std::string host, uint16_t port, + std::string agent, uint32_t length); + +std::string createOpenDHT_put(std::string key, std::string value, + uint32_t ttl, std::string client); + +std::string createOpenDHT_get(std::string key, + uint32_t maxresponse, std::string client); + +#endif + diff --git a/libretroshare/src/dht/servers.txt b/libretroshare/src/dht/servers.txt new file mode 100644 index 000000000..588cb8e95 --- /dev/null +++ b/libretroshare/src/dht/servers.txt @@ -0,0 +1,163 @@ +Wed Jan 16 04:13:01 UTC 2008 +1: 128.84.154.45:5850 planetlab6.cs.cornell.edu +2: 129.107.35.132:5850 planetlab2.uta.edu +3: 128.8.126.112:5850 pepper.planetlab.cs.umd.edu +4: 128.220.247.29:5850 planetlab2.isi.jhu.edu +5: 141.117.68.62:5850 planetlab-2.rml.ryerson.ca +6: 128.119.247.211:5850 planetlab2.cs.umass.edu +7: 129.10.120.194:5850 planetlabtwo.ccs.neu.edu +8: 152.3.138.4:5850 planetlab4.cs.duke.edu +9: 138.23.204.232:5850 planet-lab2.cs.ucr.edu +10: 192.197.121.3:5850 node-2.mcgillplanetlab.org +11: 169.229.50.8:5850 planetlab6.Millennium.Berkeley.EDU +12: 75.130.96.12:5850 75-130-96-12.static.oxfr.ma.charter.com +13: 12.46.129.21:5850 planet1.berkeley.intel-research.net +14: 128.112.139.82:5850 planetlab-8.CS.Princeton.EDU +15: 128.31.1.13:5850 planetlab3.csail.mit.edu +16: 134.121.64.4:5850 planetlab1.eecs.wsu.edu +17: 205.189.33.178:5850 planet1.ottawa.canet4.nodes.planet-lab.org +18: 143.205.172.12:5850 plab2-itec.uni-klu.ac.at +19: 192.16.125.12:5850 planetlab-2.ssvl.kth.se +20: 128.238.88.65:5850 planetlab2.poly.edu +21: 193.10.133.129:5850 planetlab-2.it.uu.se +22: 128.227.56.81:5850 planetlab1.acis.ufl.edu +23: 130.75.87.83:5850 planet1.l3s.uni-hannover.de +24: 152.3.138.3:5850 planetlab3.cs.duke.edu +25: 213.19.160.196:5850 planetlab-3.amst.nodes.planet-lab.org +26: 195.116.60.1:5850 planetlab1.warsaw.rd.tp.pl +27: 128.83.122.180:5850 planetlab2.csres.utexas.edu +28: 128.114.63.14:5850 planetslug1.cse.ucsc.edu +29: 129.174.79.248:5850 plgmu2.gmu.edu +30: 169.229.50.18:5850 planetlab16.Millennium.Berkeley.EDU +31: 138.15.10.55:5850 plab1.nec-labs.com +32: 128.208.4.197:5850 planetlab01.cs.washington.edu +33: 129.108.202.11:5850 planetlab2.utep.edu +34: 128.220.247.28:5850 planetlab1.isi.jhu.edu +35: 131.179.112.70:5850 Planetlab1.CS.UCLA.EDU +36: 169.229.50.15:5850 planetlab13.Millennium.Berkeley.EDU +37: 129.137.253.252:5850 planetlab2.uc.edu +38: 128.112.139.96:5850 planetlab-4.CS.Princeton.EDU +39: 128.232.103.201:5850 planetlab1.xeno.cl.cam.ac.uk +40: 128.208.4.199:5850 planetlab03.cs.washington.edu +41: 194.80.38.243:5850 planetlab2.cs-ipv6.lancs.ac.uk +42: 193.1.201.26:5850 planetlab-1.tssg.org +43: 193.136.191.26:5850 planetlab-2.iscte.pt +44: 150.65.32.68:5850 planet1.jaist.ac.jp +45: 136.145.115.196:5850 planetlab-02.ece.uprm.edu +46: 192.6.26.33:5850 pli2-pa-3.hpl.hp.com +47: 203.178.133.11:5850 203.178.133.11 +48: 128.31.1.12:5850 planetlab2.csail.mit.edu +49: 128.112.139.73:5850 planetlab-3.CS.Princeton.EDU +50: 129.137.253.253:5850 planetlab1.uc.edu +51: 131.246.191.41:5850 planetlab1.itwm.fhg.de +52: 129.170.214.192:5850 planetlab2.cs.dartmouth.edu +53: 128.31.1.17:5850 planetlab7.csail.mit.edu +54: 139.19.142.1:5850 planetlab01.mpi-sws.mpg.de +55: 129.105.44.253:5850 planetlab2.cs.northwestern.edu +56: 128.252.19.21:5850 vn2.cse.wustl.edu +57: 129.22.150.105:5850 planetlab-2.EECS.CWRU.Edu +58: 139.19.142.4:5850 planetlab04.mpi-sws.mpg.de +59: 142.150.238.13:5850 pl2.csl.utoronto.ca +60: 128.10.19.53:5850 planetlab2.cs.purdue.edu +61: 129.240.67.18:5850 planetlab4.ifi.uio.no +62: 128.163.142.20:5850 planetlab1.netlab.uky.edu +63: 163.221.11.74:5850 planetlab-04.naist.jp +64: 192.33.90.66:5850 planetlab1.inf.ethz.ch +65: 219.243.200.53:5850 dlut1.6planetlab.edu.cn +66: 128.112.139.78:5850 planetlab-10.CS.Princeton.EDU +67: 128.232.103.203:5850 planetlab3.xeno.cl.cam.ac.uk +68: 219.243.200.93:5850 ustc1.6planetlab.edu.cn +69: 128.42.6.143:5850 ricepl-1.cs.rice.edu +70: 152.15.98.227:5850 planetlab02.uncc.edu +71: 169.229.50.14:5850 planetlab12.Millennium.Berkeley.EDU +72: 129.22.150.90:5850 planetlab-1.EECS.CWRU.Edu +73: 128.10.19.52:5850 planetlab1.cs.purdue.edu +74: 128.252.19.20:5850 vn1.cse.wustl.edu +75: 64.161.10.2:5850 64.161.10.2 +76: 206.207.248.34:5850 planetlab1.arizona-gigapop.net +77: 128.208.4.198:5850 planetlab02.cs.washington.edu +78: 169.229.50.11:5850 planetlab9.Millennium.Berkeley.EDU +79: 128.232.103.202:5850 planetlab2.xeno.cl.cam.ac.uk +80: 141.213.4.201:5850 planetlab1.eecs.umich.edu +81: 63.64.153.84:5850 63.64.153.84 +82: 163.221.11.71:5850 planetlab-01.naist.jp +83: 128.208.4.99:5850 planetlab04.cs.washington.edu +84: 128.151.65.102:5850 planet2.cs.rochester.edu +85: 12.46.129.15:5850 planet5.berkeley.intel-research.net +86: 130.161.40.153:5850 planetlab1.ewi.tudelft.nl +87: 139.19.142.5:5850 planetlab05.mpi-sws.mpg.de +88: 141.76.45.17:5850 planet1.inf.tu-dresden.de +89: 150.65.32.66:5850 planet0.jaist.ac.jp +90: 128.119.247.210:5850 planetlab1.cs.umass.edu +91: 128.223.8.112:5850 planetlab2.cs.uoregon.edu +92: 132.68.237.34:5850 ds-pl1.technion.ac.il +93: 152.3.138.5:5850 planetlab5.cs.duke.edu +94: 132.252.152.194:5850 planetlab2.exp-math.uni-essen.de +95: 128.31.1.14:5850 planetlab4.csail.mit.edu +96: 64.161.10.3:5850 64.161.10.3 +97: 63.64.153.82:5850 63.64.153.82 +98: 192.42.83.252:5850 192.42.83.252 +99: 130.136.254.21:5850 planetlab1.CS.UniBO.IT +100: 128.59.20.226:5850 planetlab1.cs.columbia.edu +101: 128.192.101.217:5850 itchy.cs.uga.edu +102: 128.2.223.65:5850 PLANETLAB-3.CMCL.CS.CMU.EDU +103: 128.59.20.227:5850 planetlab2.cs.columbia.edu +104: 128.31.1.11:5850 planetlab1.csail.mit.edu +105: 128.220.231.3:5850 128.220.231.3 +106: 63.64.153.83:5850 63.64.153.83 +107: 128.8.126.111:5850 salt.planetlab.cs.umd.edu +108: 128.31.1.16:5850 planetlab6.csail.mit.edu +109: 128.220.231.2:5850 128.220.231.2 +110: 129.10.120.193:5850 planetlabone.ccs.neu.edu +111: 75.130.96.13:5850 75-130-96-13.static.oxfr.ma.charter.com +112: 202.244.160.251:5850 202.244.160.251 +113: 128.42.6.145:5850 ricepl-3.cs.rice.edu +114: 194.29.178.13:5850 planetlab3.mini.pw.edu.pl +115: 192.33.210.16:5850 lsirextpc01.epfl.ch +116: 169.229.50.16:5850 planetlab14.Millennium.Berkeley.EDU +117: 128.252.19.22:5850 vn3.cse.wustl.edu +118: 194.70.143.50:5850 system18.ncl-ext.net +119: 143.215.129.115:5850 planet2.cc.gt.atl.ga.us +120: 141.24.249.130:5850 planetlab2.fem.tu-ilmenau.de +121: 132.68.237.36:5850 ds-pl3.technion.ac.il +122: 35.9.27.26:5850 planetlab1.cse.msu.edu +123: 195.130.121.204:5850 planetlab1.cs.uoi.gr +124: 203.178.133.3:5850 planetlab1.otemachi.wide.ad.jp +125: 128.135.11.149:5850 planetlab1.cs.uchicago.edu +126: 200.132.0.70:5850 planetlab2.pop-rs.rnp.br +127: 150.165.15.19:5850 planetlab2.lsd.ufcg.edu.br +128: 128.84.154.49:5850 planetlab1.cs.cornell.edu +129: 192.6.19.120:5850 grouse.hpl.external.hp.com +130: 193.136.227.163:5850 planetlab1.fct.ualg.pt +131: 158.130.6.254:5850 planetlab1.cis.UPENN.EDU +132: 194.36.10.154:5850 194.36.10.154 +133: 69.110.237.115:5850 69.110.237.115 +134: 194.80.38.242:5850 planetlab1.cs-ipv6.lancs.ac.uk +135: 128.138.207.181:5850 planetlab1.cs.colorado.edu +136: 129.69.210.97:5850 planetvs2.informatik.uni-stuttgart.de +137: 141.76.45.18:5850 planet2.inf.tu-dresden.de +138: 216.165.109.82:5850 planet2.scs.cs.nyu.edu +139: 128.223.8.113:5850 planetlab3.cs.uoregon.edu +140: 128.238.88.64:5850 planetlab1.poly.edu +141: 12.46.129.22:5850 planet2.berkeley.intel-research.net +142: 131.246.191.42:5850 planetlab2.itwm.fhg.de +143: 129.130.252.138:5850 plab1.eece.ksu.edu +144: 219.243.200.81:5850 uestc1.6planetlab.edu.cn +145: 129.82.12.187:5850 planetlab-1.cs.colostate.edu +146: 140.247.60.126:5850 righthand.eecs.harvard.edu +147: 132.252.152.193:5850 planetlab1.iem.uni-due.de +148: 12.46.129.14:5850 planet4.berkeley.intel-research.net +149: 128.59.20.228:5850 planetlab3.cs.columbia.edu +150: 192.42.83.251:5850 192.42.83.251 +151: 128.84.154.71:5850 planetlab2.cs.cornell.edu +152: 203.30.39.241:5850 planetlab2.singaren.net.sg +153: 129.170.214.191:5850 planetlab1.cs.dartmouth.edu +154: 220.245.140.197:5850 220-245-140-197.static.tpgi.com.au +155: 133.11.240.56:5850 planetlab1.iii.u-tokyo.ac.jp +156: 129.69.210.96:5850 planetvs1.informatik.uni-stuttgart.de +157: 129.108.202.10:5850 planetlab1.utep.edu +158: 193.174.67.186:5850 planet01.HHI.FRAUNHOFER.DE +159: 128.135.11.152:5850 planetlab3.cs.uchicago.edu +160: 206.117.37.4:5850 206.117.37.4 +161: 219.243.201.17:5850 thu2.6planetlab.edu.cn +162: 155.98.35.2:5850 planetlab1.flux.utah.edu