Blog się już zdążył trochę zakurzyć, więc postanowiłem dodać nowy wpis o programie, którego miałem czelność spłodzić jakiś miesiąc temu. Sam pomysł ma już rok. Zastanawiałem się wtedy nad możliwościami obejścia limitów transferu w sieci lokalnej. Często potrzebowałem zciągnąć duży plik z serwera HTTP w jak najszybszym czasie (np. obraz ISO), ale ograniczenie transferu czas ten niemiłosiernie wydłużało. Wiedząc, że sztywne ograniczenie pasma jest przydzielane do konkretnego interfejsu sieciowego łatwo możemy dojść od wniosku, że powielając interfejsy sieciowe i poprzez każdy z nich zaciągając innych fragment danego pliku (HTTP 1.1 pozwala na to) jednocześnie skracamy czas pobrania, a więc i sumaryczny transfer.
Do realizacji zabrałem się dopiero po dłuższym czasie. Wziąłem w obroty bibliotekę Jpcap. Prosta i wygodna biblioteka do przechwytywania i generowania pakietów TCP/IP/Ethernet itp. w języku Java. Wykorzystuje do tego sławna bibliotekę WinPcap/libpcap. Więcej informacji na stronie projektu: http://netresearch.ics.uci.edu/kfujii/jpcap/doc/ .
Potrzebowałem napisać kilka klas do obsługi ruchu TCP. Przez to że samodzielnie generowałem pakiety i wysyłałem je „surowo” w sieć, cały ruch musiał być obsłużony przez moją aplikacje. Jpcap był tylko interfejsem pozwalającym przyjmować i wysyłać pakiety. Po kilku godzinach przegryzania się przez dokumenty RCF zabrałem się do pisania. Okazało się, że obsłużyć ruch TCP/IP na minimalnym potrzebnym mi poziomie wcale tak trudno nie jest: 3-way handshake jak i odpowiedzi na ruch ARP nie sprawiły żadnego problemu. Trochę więcej czasu spędziłem na wymyśleniu w miarę wydajnego układania pakietów w buforze (niestety to ja musiałem dbać o ich kolejność), obsłudze duplikacji pakietów i próśb o ponowne przesłanie tych które nie dotarły. Pomocna przydała się lektura kodu systemu Jnode (http://jnode.org). W pewnym momencie zastanawiałem się nawet nad przeportowaniu jego stosu TCP/IP do mojego projektu, ale po kilkugodzinnej jego lekturze stwierdziłem, że potrzebnych będzie mi niewiele tych funkcjonalności, które są tam zawarte, a poznanie architektury i śledzenie błędów w takim przeportowanym stosie pochłonie więcej pracy niż napisanie stosu „po swojemu”.
Po napisaniu obsługi ruchu TCP/IP oraz ARP najtrudniejszy fragment projektu był już za mną. Później powstały klasy obsługujące HTTP (też w minimalnej, absolutnie minimalnej postaci), klasa zajmująca się zarządzaniem wątkami pobierania i na końcu prosty interfejs. Sam program uruchamiamy z linii poleceń poprzez „java –jar Cap.jar [parametry] URL”, gdzie URL to adres zasobu a parametry to:
–help [-h] pomoc
–version [-v] informacje o wersji
–file FILE [-f FILE] plik wyjściowy o nazwie FILE
–dump-interfaces wylistuj dostępne interfejsy sieciowe
–config FILE [-c FILE] ścieżka do pliku konfiguracyjnego
–verbosity-level LEVEL stopień “rozgadania” programu
[-vl LEVEL] od 0 do 6
Konfiguracja interfejsów sieciowych umieszczona jest w pliku cfg.ini (domyślnie). Oto przykładowa zawartość:
cap.version=0interfaces.count=3
interfaces.device=0interface.0.name=komp_tomka
interface.0.mac=00:a0:d2:1a:74:a0
interface.0.ip=192.168.0.200interface.1.name=komp_kasi
interface.1.mac=00:a0:d2:1a:74:a1
interface.1.ip=192.168.0.201interface.2.name=komp_radka
interface.2.mac=00:a0:d2:1a:74:a2
interface.2.ip=192.168.0.202interface.3.name=komp_elzbietki
interface.3.mac=00:a0:d2:1a:74:a3
interface.3.ip=192.168.0.203
Objaśnienie:
cap.version wersja programu dla którego przeznaczona jest konfiguracja
interfaces.count ilość wirtualnych interfejsów to utworzenia
interfaces.device numer fizycznego urządzenia, z którego będziemy korzystali
interface.X.name nazwa dla interfejsu X
interface.X.mac MAC interfejsu X
interface.X.ip IP interfejsu X
Samego programu nie mogę nawet nazwać alphą. Ma wiele błędów, ale zamieszczam go w szeroko pojętych celach edukacyjnych. Ufam, że kiedyś może się komuś przydać. Publikuje go na nowej licencji BSD, więc użycie mojego kodu w waszych projektach nie powinno stanowić problemu. Tutaj zamieszczam archiwum z programem. W pliku Cap.jar są też źródła. Miłej lektury.