Posts tagged ‘computer networks’

Pimp My WLAN

2012-03-03 20:41

About two weeks ago I moved to Netherlands, landing in a medium-sized but cozy town of Groningen. This of course deserves a general blogpost on its own right (more than a single one, in fact), but the story I wanted to share today is extremely specific. For the most part, it’s also purely technical, exhibiting typical hacker’s dynamics. An overarching theme is an “itch” that needs to be scratched.

Let’s start then, first by defining the problem at hand.

On architectural features

I happen to live in a square which is referred to as town’s center, where significant fraction of buildings – maybe even majority – look kinda like this. Don’t pay too much attention to the outside appearance, as it can be very misleading. Despite their seemingly old architectural style, they’re often quite new and modern, but have been “retrofitted” to match the surrounding urban landscape. Final effect is rather pleasing aesthetically, I’d say.

What is more important and relevant here, though, is the size of windows. By my standards at least, they are simply enormous – and this fact precludes simple evaluation. (On one hand, there’s a lot of sunlight! On the other hand, there’s a lot of sunlight…). Moreover, it hints at how remarkably long the vertical distance between floor and the ceiling is. In my case, it’s about 2.8 m (that’s 9 ft for you Imperalists), having a significant impact on how spacious the apartment feels.

On insufficiently vertical waves

But for the issue I want to talk about, this was actually a downside. The matter concerns Internet access, which is shared among mine and three neighboring apartments through a Wi-Fi network with a single access point. In theory, the area it has to cover spans just couple of meters. In practice, however, it’s hindered not only by walls and doors, but also – and maybe even primarily – but this significant distance along the vertical axis.

See, most of the typical household wireless routers have directional antennae which are deliberately set to output signal mostly in the horizontal plane. While this allows for a single AP to easily cover even big apartment, it is also a liability in a setting similar to mine. Because the access point is on ground floor, it fails to appropriately cover the higher levels. And since this includes the very place I’m living in, I’ve been having rather annoying problems caused by signal’s low strength and quality: dropped packets, lost connections, and all that stuff. Even web browsing (or similar activities that doesn’t really depend on latency) has been very cumbersome, despite sitting less than 5 meters in straight line from the access point! It’s almost amazing how one can get screwed over by such simple design limitation like the direction of an antenna.

So, you can easily see how this was a problem that yearned to be solved. But how? One does not simply make the waves go further, right?…

On re-purposing of the old hardware

Actually, this is perfectly possible: devices known as WLAN repeaters do just that. Serving as sort of amplifier, they can extend the range of wireless network by relaying its signal between base access point and the final receiver, e.g. WLAN interface in a laptop. Basic physics suggest that it obviously cannot be done for free, so side effects include decreased performance of such range-extended networks due to reduced bandwidth. But where applicable, this solution is usually worth its while.


The Router

My scenario was definitely one of those, as I vastly prefer “not ideal Wi-Fi connectivity” to “almost no Wi-Fi connectivity at all”. So I went to investigate how I could procure such a device. Specifically, I had an old router lying around unplugged and useless – and it quickly gained my attention.

I cannot say that I’m any sort of expert when it comes to telecommunication, electronics or hardware of any kind (that’s vastly below the level abstraction I typically operate on), but I have some basic idea of what a wireless router really is. Elementary deduction suggest it’s a transceiver, an equipment able to receive and send out radio signals. What those signals are – that should be pretty much irrelevant, as long as (1) they fit into physical characteristics of the device and (2) the only thing we want to do is to propagate them further.

In short, it should be capable of acting as a repeater! Yay?

On awesomeness of the open source

Well, not really – not at a first glance, at least. While many routers feature the repeater option in their firmware, mine is somewhat old and low-end model: it doesn’t even support IPv6, not to mention goodies like the 802.11n band. Acting as a relay was also on this “nay” list, because being an ordinary access point is pretty much the only thing this inconspicuous black box used to know.

But thanks to one impressive piece of hackery, it was possible for its limitations to be lifted. What I’m talking about is DD-WRT – a community project that provides a custom firmware for variety of different models of popular routers. This firmware is very powerful and allows to easily tap into device’s hidden power, exposing capabilities omitted in vendor software. In my case, it promised to provide the crucial Client Bridge feature: ability to create more then one virtual, wireless interface and form a bridge between them in order to relay network traffic.

On thrills & perils of low-level hacking

I set to try it out – and it turned out to be non-trivial, to say the least. Some steps of the process were amusing due to their obscurity – like setting up a local server for the archaic TFTP protocol. Turns out it was needed for the actual transfer of new firmware and a small Linux distro that works on top of that. I suppose you have to do same when installing Linux on a microwave, but admittedly, I haven’t tried that just yet ;)

The most troublesome part was actually the very beginning. It involved connecting to the device via Ethernet wire and then telnetting at the right moment during it’s boot-up. This way, it is possible to access the RedBoot bootstrapping shell and perform all kinds of surgery on software internals.
Unfortunately, the instruction for making this happen was hopelessly unclear. I spent good several quarters troubleshooting any potential issues, even going as far as to use Wireshark to monitor any traffic originating from the router, looking into how it identifies itself within this crude two-node network.

Fortunately, I’ve later found a much better instruction that didn’t lack the rather important part about holding down the RESET button for, well, long time. From there everything went rather smoothly.

On trickery of network management

The last part was tweaking numerous options and settings in DD-WRT’s web interface in order to make the router talk to its cousin downstairs. This level of abstraction was obviously much more comfortable for me to work at. Still, there was some sorcery involved, as in deciding whether I’d like to have my own subnet or operate within existing one – essentially a choice between WLAN-to-WLAN router or “switch”. The second option was of course much more appealing because it was completely transparent to clients. Choosing it, I didn’t have to reconfigure the vast multitude of my 3 (three) devices that use Wi-Fi :)

This variant ended up being more complicated, though. And again, I have found both good and rather crappy instructions on how to make it happen – but unlike last time, now they were both coming from the DD-WRT wiki. Well, seems like documentation is not among the strongest sides of this project…

It works!

But rest assured: this story has a happy ending :) Yes, it was preceded by juggling IP configuration of my PC and few reboots of the router, but it would be malicious to consider this as something more than a little nuisance.

So, what’s the point in all of this?… I guess the bottom line would be about not being afraid to experiment if something needs to be improved. Risk aversion is powerful, true – but sometimes even failure is not that bad, especially if everything remains inside the realm of software. Here, even if you “blow” something up there will be no holes left to cover with duct tape ;-)

Checking Whether IP is Within a Subnet

2012-02-04 22:11

Recently I had to solve a simple but very practical coding puzzle. The task was to check whether an IPv4 address (given in traditional dot notation) – is within specified network, described as a CIDR block.
You may notice that this is almost as ubiquitous as a programming problem can get. Implementations of its simplified version are executed literally millions (if not billions) of times per second, for every IP packet at every junction of this immensely vast Internet. Yet, when it comes to doing such thing in Python, one is actually left without much help from the standard library and must simply Do It Yourself.

It’s not particularly hard, of course. But before jumping to a solution, let’s look how we expect our function to behave:

  1. >>> ip_in_network("10.0.0.0", "10.0.0.0/8")
  2. True
  3. >> ip_in_network("127.0.56.34", "127.0.0.0/8")
  4. True
  5. >> ip_in_network("192.168.0.0", "192.168.224.0/24")
  6. False

Pretty obvious, isn’t it? Now, if you recall how packet routing works under the hood, you might remember that there are some bitwise operations involved. They are necessary to determine whether specific IP address can be found within given network. However low-level this may sound, there is really no escape from doing it this way. Yes, even in Python :P

It goes deeper, though. Most of the interface of Python’s socket module is actually carbon-copied from POSIX socket.h and related headers, down to exact names of particular functions. As a result, solving our task in C isn’t very different from doing it in Python. I’d even argue that the C version is clearer and easier to follow. This is how it could look like:
#include
#include
#include
#include

bool ip_in_network(const char* addr, const char* net) {
struct in_addr ip_addr;
if (!inet_aton(addr, &ip_addr)) return false;

char network[32];
strncpy(network, net, strlen(net));

char* slash = strstr(network, “/”);
if (!slash) return false;
int mask_len = atoi(slash + 1);

*slash = ‘\0’;
struct in_addr net_addr;
if (!inet_aton(network, &net_addr)) return false;

unsigned ip_bits = ip_addr.s_addr;
unsigned net_bits = net_addr.s_addr;
unsigned netmask = net_bits & ((1 << mask_len) - 1); return (ip_bits & netmask) == net_bits; }[/c] A similar thing done in Python obviously requires less scaffolding, but it also introduces its own intricacies via struct module (for unpacking bytes). All in all, it seems like there is not much to be gained here from Python’s high level of abstraction.

And that’s perfectly OK: no language is a silver bullet. Sometimes we need to do things the quirky way.

Tags: , , ,
Author: Xion, posted under Computer Science & IT » 3 comments

Wesołe jest życie admina

2008-12-23 21:01

Dwa komputery i jedno łącze internetowe to pewien kłopot, jeśli chcemy mieć dostęp do sieci na wszystkich maszynach jednocześnie. Istnieje oczywiście możliwość mostkowania (nazywanego w Windows udostępnianiem połączenia), ale wada tego rozwiązania jest znaczna: maszyny stają się od siebie zależne i jedna nie będzie miała dostępu do sieci bez drugiej. Na dłuższą metę jest to raczej niewygodne.
Aż dziwne, że dojście do tego wniosku zajęło mi ładnych parę miesięcy ;) W każdym razie nadarzyła się dobra okazja, by sytuację tę zmienić, więc parę dni temu zaopatrzyłem się w proste urządzenie sieciowe zwane potocznie routerem (chociaż faktycznie chodzi o switch routujący).

Przy tej okazji zauważyłem kilka dość zaskakujących dla mnie faktów. Ogólnie wygląda bowiem na to, że tworzenie domowych sieci stało się już tak bardzo powszechne, że urządzenia takie jak to nabyte przeze mnie są obecnie bardzo tanie. Za nieco ponad sto złotych można już mieć pudełko z powodzeniem radzące sobie ze sterowaniem ruchem w niewielkiej sieci, niekoniecznie przewodowej.
Druga niespodzianka związana była z tym, co było dołączone do urządzenia. Bo co niby może znajdować się na płycie CD, którą to – jak każe instrukcja – należy odczytać jeszcze przed podłączeniem routera? Raczej wątpliwe, by były to sterowniki :) Zagadka wyjaśniła się po zalogowaniu do panelu administracyjnego routera: otóż jest to sprytny programik, który odczytuje ustawienia komputera podłączonego bezpośrednio do Internetu, by potem skopiować je na router. Tym sposobem powinniśmy być w stanie skonfigurować urządzenie nawet wtedy, gdy ‘przeglądarka’ i ‘Internet’ to dla nas jedno i to samo… cóż, przynajmniej w teorii ;)

Oczywiście nie sprawdzałem tego w praktyce, bo zdecydowanie wolę tradycyjną metodę konfiguracji. To znacznie fajniejsze – podobnie zresztą jak dalsze grzebanie w ustawieniach routera i obserwowanie, jak to pakiety zdążają we właściwych sobie kierunkach :D

Tags: , ,
Author: Xion, posted under Internet, Life » 7 comments

O (nie)zawodności TCP

2008-06-06 20:43

Dowiadując się, czym jest protokół TCP, można przy okazji usłyszeć lub przeczytać, że jest on niezawodny (reliable). Można wtedy pomyśleć, że to jakiś rodzaj białej magii – zwłaszcza, gdy pomyślimy sobie, jakie przeszkody mogą spotkać przesyłany kawałek danych podczas podróży tysiącami kilometrów kabli (a ostatnio i bez nich). Zatory w transmisji, źle skonfigurowane routery, nagła zmiana topologii sieci, i tak dalej… Mimo to niektóre programistyczne interfejsy próbują nam wmówić, że odczyt i zapis danych “w sieci” jest w gruncie rzeczy niemal identyczny np. z dostępem do dysku. To pewnie też skutek “myślenia magicznego” na temat pojęcia niezawodności w kontekście TCP.

A w praktyce nie kryje się za nim żadna magia. Niezawodność TCP ma swoje granice i obsługuje dokładnie tyle możliwych sytuacji i zdarzeń losowych, ile zostało przewidzianych – jawnie lub nie – w specyfikacji tego protokołu. (Zawartej w RFC 793, jeśli kogokolwiek ona interesuje ;]). Analogicznie jest na przykład z dostępem do dysków wymiennych: stare wersje Windows potrafiły radośnie krzyknąć sławetnym bluescreenem, gdy użytkownik ośmielił się wyciągnąć dysk z napędu w trakcie pracy aplikacji, która z niego korzystała. Była to bowiem sytuacja nieprzewidziana na odpowiednio wysokiej warstwie systemu.
Jakie więc niespodziewane sytuacje i problemy dotyczące TCP należy przewidywać, jeśli piszemy programy sieciowe? Jest ich przynajmniej kilka:

  • Pakiety TCP po drodze od nadawcy i odbiorcy mogą ulegać podzieleniu (fragmentacji) w celu przepchnięcia ich przez podsieci o różnych możliwościach przesyłu. Wszystkie kawałki są oczywiście składane przez odbiorcę w miarę ich napływania wraz z dodatkowymi informacjami, pozwalającymi na odtworzenie kolejności bajtów. Jednak fragmentacja sprawia, że nie musimy odebrać danych w porcjach tej samej długości, w jakiej były wysyłane. Dowolna ilość wywołań funkcji typu Send u nadawcy może przekładać się na równie dowolną liczbę wywołań Receive w celu odebrania wysłanych informacji. Stąd wynika konieczność rozróżniania porcji danych we własnym zakresie, o czym pisałem jakiś czas temu.
  • Połączenie TCP może się zakończyć się nieoczekiwanie, jak choćby poprzez nagłe zakończenie wykorzystującego je procesu u jednej ze stron komunikacji. Wykrycie takiej sytuacji polega niestety wyłącznie na opóźnieniach (timeout) w otrzymywaniu pakietów potwierdzających (ACK) dostarczanie danych. To sprawia, że nie można odróżnić zerwania połączenia od zatorów w transmisji na poziomie samego protokołu TCP.
    Dlatego też trzeba sobie z tym radzić na wyższym poziomie, implementując w protokołach aplikacyjnych mechanizmy typu ping-pong do okresowego sprawdzania, czy połączenie “żyje”. Należy przy tym sprawdzać czas odpowiedzi nie względem jakichś twardych limitów, tylko poprzednio rejestrowanych interwałów.
  • Diagram stanów połączenia TCP
    Diagram stanów
    połączenia TCP

    Wreszcie, połączenie TCP można też zakończyć grzecznie (wymianą pakietów z flagami: FIN, FIN/ACK i ACK), co powinno dać się wykryć przez sieciowy interfejs programistyczny. W praktyce bywają z tym problemy, a jako takie powiadamianie o rozłączeniu działa tym lepiej, im niższy poziom API jest używany. W miarę pewnie wygląda to na warstwie POSIX-owych gniazdek (w Windows zaimplementowanych jako biblioteka WinSock) oraz w ich bezpośrednim opakowaniu na platformie .NET (System.Net.Sockets.Socket) lub w Javie (java.net.Socket). Wraz ze wzrostem poziomu abstrakcji (jak chociażby w specjalizacjach “sieciowych” strumieni I/O) sprawa wygląda już nieco gorzej…

Z niezawodnością TCP nie ma co więc przesadzać. W szczególności nie powinniśmy oczekiwać, że zapewni nam ona ochronę przed wszystkimi wyjątkowymi sytuacjami, jakie mogą wydarzyć się podczas komunikacji sieciowej. O przynajmniej kilku musimy pomyśleć samodzielnie.

Tags: , ,
Author: Xion, posted under Internet, Programming » Comments Off on O (nie)zawodności TCP

Łapacz pakietów

2008-03-02 18:10

Oprogramowanie open source nie grzeszy zazwyczaj jakością, lecz od każdej reguły istnieją przecież wyjątki. Ostatnio znalazłem właśnie taki wyjątek; należy on do tej kategorii programów, które wymagają pewnego przygotowania, jeśli chcemy z nich korzystać efektywnie. Lecz mimo tego, iż jest to dość specjalistyczne narzędzie, nie sposób przy jego pomocy zrobić krzywdy swojemu systemowi. Warto się więc mu przyjrzeć, bo wśród tego rodzaju programów jest ono prawdopodobnie jednym z najlepszych.
Logo WiresharkaMam na tu na myśli analizator pakietów sieciowych Wireshark. Przy jego pomocy możemy bez większych problemów podejrzeć, cóż takiego jest przesyłane wzdłuż biegnących od naszego komputera kabli (względnie fal radiowych). Takie programy są popularnie nazywane snifferami i mogą służyć do bardzo wielu pożytecznych celów oraz kilku innych, mniej chwalebnych ;-)

Wśród wyróżniających cech Wiresharka trzeba na pewno wymienić interfejs, który jest przejrzysty, a przy tym funkcjonalny – co nie zdarza się często nawet wśród nie-GPL-owych programów. Bez większych problemów możemy złapane pakiety przeglądać i filtrować według wielu różnych kryteriów. Mogą one obejmować także cechy dot. specyficznych protokołów sieciowych (możemy np. wyświetlić pakiety HTTP z żądaniami typu GET). A tych wspieranych przez program jest zresztą całkiem sporo. Pakiety należące do znanych protokołów są oczywiście automatycznie rozkodowywane i pokazywane w przyjaznej postaci z podziałem na warstwy OSI, pola w nagłówkach oraz zasadniczą treść.

Screen z programu Wireshark

To oczywiście nie wszystko; do innych bardzo użytecznych funkcji należy chociażby możliwość wyodrębnienia całego strumienia TCP (czyli np. “rozmowy” jakiejś aplikacji ze zdalnym serwerem). Podobnie przydatnych narzędzi jest zresztą więcej i ciężko byłoby je wszystkie tu wymienić.
Dodatkowo program ten jest wybitnie wszędobylski i posiada równoważne wersje dla prawie każdego sensownego systemu operacyjnego, z Windows i przeróżnymi Linuksami włącznie. Biorąc pod uwagę to, że działa sprawnie, szybko i intuicyjnie, trzeba przyznać, że to nieoceniony instrument dla programisty piszącego aplikacje sieciowe.

Tags: , ,
Author: Xion, posted under Applications, Internet » 8 comments
 


© 2017 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.