Zajímalo by mě, jak co nejlépe (ne nutně nejjednodušeji) vyřešit problém NATu, tedy spojit dva klienty za routerem který používá NAT a klienti naprosto nemají šanci cokoliv změnit, tedy třeba přesvědčit ISP aby mu namapoval port. Jde mi tedy o to jak co nejlépe nakombinovat existující knihovny které slouží k tomuto účelu, jazykem použitým pro takový program by mělo být C/C++ a nebo by měl existovat port. Nalezl jsem několik řešení, ale žádné nevyužívá všechny techniky co pro toto existují, o multiplatformnosti nemluvě. Každopádně řešení MUSÍ fungovat i pod Windows, protože tam je největší potenciální uživatelská základna pro to co chci.
Hlavní požadavek: Mějme aplikaci kde uživatelé mají 160bitový identifikátor, třeba SHA1 jejich MAC adresy. Požadavkem je aby se kterýkoliv uživatel mohl přímo spojit s jakýmkoliv jiným bez ohledu na to, kde se ve struktuře sítě nachází, ať již za NATem a nebo mají veřejnou IP. Předpokladem je že existuje alespoň jeden uzel overlay sítě s veřejnou IP, ten by ale neměl být použít jako proxy, nanejvíš nějak dopomoci ustavení spojení. Komunikace musí být asynchronní, ale to je snad standard.
Co jsem nalezl:
libnice:
http://nice.freedesktop.org/wiki/ - jde prý zkompilovat i pod Windows, dle zdrojáku si asi trochu rozumí i s UPnP, ale podpora pro NAT-PMP zatím chybí.
libjingle:
http://code.google.com/p/libjingle/ - mělo by se umět dobře dostat přes NAT, ale prý je to prasácky udělaná knihovna plně nekompatibilní s Jingle protokolem a po té co to Google zveřejnil tak toho hodně změnil na své straně, nevím jestli tuhle a nebo libnice
miniupnp:
http://miniupnp.free.fr/ - umí komunikovat s routerem podporujícím UPnP (ale už ne dva UPnP routery za sebou, časté v mnoha domácnostech...) a má v sobě i NAT-PMP podporu
ICE/zeroc:
http://www.zeroc.com/ - zdá se pěkné pro tvorbu distribuovaných aplikací, pěkný example chatu a podpora mnoha jazyků
zeromq:
http://www.zeromq.org/ - odlehčená alternativa k ICE
boost/asio:
http://www.boost.org/doc/libs/1_49_0/doc/html/boost_asio.html - asi nejjednodušší na použití, multiplatformní, podpora NATu nejistá
Tak - a jakým způsobem tyto knihovny nakombinovat a schovat je pod nějaké další rozhraní, které si samo určí co použije.
Rozhraní (dejme mu název třeba bitlegion) bude mít pouze tyto funkce :
1) inicializace a ukončení - nějaké bitlegion_init() a bitlegion_exit()
2) získání bloku dat podle jeho sha1 hashe - handle = bitlegion_getblock_async(sha1_hash) které vrátí "něco" pro kontorlu jestli data už dorazila
3) bitlegion_check(handle) => enum {SEARCHING, SUCCESS, NOT_FOUND} - tedy něco na kontrolu hledání bloku, jestli zatím hledá, byl získán, a nebo nebyl nalezen
4) bitlegion_get_data(handle, &pdata, &pdatasize) pro získání dat
takže to bude fárat
main() {
BitLegion bl = bitlegion_init(...); // connect etc.
...
handle = bitlegion_get_block_async(bl,"BL5OM7M75DWHAXMFZFJ23MU3LVMRXKFO6HTGUTY");
...
stop = false;
while (!stop) {
if (bitlegion_check(bl,handle)) {
bitlegion_get_data(bl, handle, &data, &dataSize);
stop = true;
}
}
... // use data
bitlegion_exit(bl);
}
BTW jaký je váš názor na architekturu navrhované "knihovny", je to vhodný přístup? Zas tolik zkušeností nemám abych to byl schopen rozhodnout, jestli je to dobrý návrh pro knihovnu která má umožnit získávat bloky dat na základě jejich hashe.
Mimochodem nějaký týpek se snaží o něco podobného, tak ho nějakou dobu sleduji, ale neřeší NAT traversal a používá boost asio a ani nemá představu o struktuře overlay p2p sítě (já chci něco na způsob chordu - tedy DHT, a ne jen friend to friend):
http://bithorde.org/