CJC i PyXMPP 1.0.1

Ostatnie wydanie CJC i PyXMPP było ponad trzy lata temu – w grudniu 2005 roku. Po tamtym wydaniu zacząłem poważne zmiany w API… i nigdy ich nie skończyłem, a niedokończonego dzieła wydawać nie chciałem. Potem przyszły kłopoty ze zdrowiem, pośrednio wynikłe też z mojego zaangażowania w Open Source (czyt. siedzenia całymi dniami przed kompem, świata nie widząc) i postanowiłem unikać angażowania się w kodowanie. Tak więc, planowane zmiany nigdy nie miały być dokończone.

W międzyczasie jednak w starym kodzie znajdowane były błędy, od czasu do czasu jakiś błąd poprawiłem, czasem ktoś podesłał patcha, to wrzucałem do SVN. Pojawiały się nowe wersje Pythona, czy M2Crypto, to kod dostosowywałem odpowiednio (CJC używam na co dzień, moja żona też, więc to musi działać). Właściwie, jak ktoś jeszcze używał PyXMPP albo CJC, to któryś z ostatnich snapshotów.

Ostatnio zastanawiałem się też, czy nie spróbować do CJC wreszcie dodać obsługi UTF-8. Wcześniej tego odmawiałem, bo Pythonowy moduł curses w ogóle nie ma obsługi Unicode, tylko start 8-bitowe API. I nic nie wskazuje na to, że to ktoś poprawi, ale uż jakiś czas temu jeden z użytkowników udowadniał mi, że to się jednak da zrobić, jeśli tylko moduł curses jest zlinkowany z biblioteką „libncursesw”. W PLD długo tak nie było, ale w Th już jest. To czemu by nie spróbować?

Wczoraj więc spróbowałem. Wyświetlanie UTF-8 działało bez żadnych zmian w kodzie, ale żeby wczytywać znaki Unicode z klawiatury musiałem dodać brzydkiego hacka. I w ogóle trochę obsługi klawiatury przerobić. Udało się. A skoro wreszcie się pojawiła funkcjonalność tak wyczekiwana przez użytkowników, to czemu by nie wydać nowej wersji? Resztę dnia spędziłem
przygotowując paczki z PyXMPP 1.0.1 (w tym jeszcze przed wydaniem poprawiłem jednego paskudnego babola) i CJC 1.0.1. Dzisiaj wysłałem informacje o wydaniach na listy mailowe dotyczące tych produktów. No to chyba udało mi się coś wydać. :-)

Po następne wersje zapraszam za trzy lata. ;-)

Uffff… działa

Okazało się, że wystarczyło: ifdown eth1; ifup eth1. Widać
znowu zgłupiała moja super sieciówka na USB… albo switch do którego jest
podłączona.

A niedziałanie DNSu, a co za tym idzie i mojego joggera, wynikało z mojej
własnej głupoty. W rekordzie SOA miałem bzdurne czasy wpisane i zgodnie z tymi
wytycznymi zapasowe serwery DNS zapominały o jajcu.net najpóźniej w
godzinę po padzie mojego serwerka. Widać kiedyś chciałem wymusić szybsze
odświeżanie strefy, a nie chciało mi się do dokumentacji zaglądać który
numerek co oznacza. Zmniejszyłem tymczasowo prawie wszystkie… i tak
już zostało. Teraz ustawiłem expire na trzy tygodnie i wreszcie
zapasowe serwery nazw powinny spełniać swoją rolę jak należy.

Jabberowi admini, pamiętajcie o rekordach SRV!

Na moim nowym Jabberowym koncie wszystko działa ślicznie. No, prawie
wszystko. Okazało się, że brak jest komunikacji z pojedynczymi serwerami,
a niektóre z innych serwerów lub usług odpowiadają z dużym opóźnieniem.
Większość z tych problemów okazała się mieć związek z rekordami SRV, służącymi
do lokalizacji właściwego serwera Jabbera.

Moja domena nie ma i raczej nie będzie miała rekoru A. Serwer pocztowy
jest wskazywany przez rekord MX, serwer Jabbera przez SRV, strony WWW są
w poddomenach. Rekord A dla domeny nie ma sensu, bo niby na co miałby
wskazywać, jeżeli każda usługa może być obsługiwana przez inną maszynę?
Niestety, niektóre serwery Jabbera wciąż mają problemy z poprawnym obsłużeniem
rekordów SRV. Albo od razu dobijają się do rekordu A, albo szukają
niewłaściwego SRV, np. „_jabber._tcp”, które może było dobre, ale z trzy lata
temu, przed opublikowaniem RFC ze specyfikacją XMPP. W obu przypadkach
wystarczy poprawa konfiguracji serwera (nie sądzę, żeby któraś z implementacji
jeszcze nie miała obsługi SRV).

To tyle o moim rekordzie SRV. To jednak działa także w drugą stronę.
Zauważyłem, że mam straszne opóźnienia przy łączeniu się z konferencjami na
chat.chrome.pl, a także przy wysyłaniu tam wiadomości po dłuższej przerwie.
Okazało się, że serwer po prostu czeka na odpowiedź na zapytanie
o _xmpp-server._tcp.chat.chrome.pl, potem wersję
z „_jabber._tcp”, a na końcu dopiero pobiera rekord A. Jeden drobny wpis w DNS
by starczył, żeby działało to szybciej (myślę, że niedługo to będzie
poprawione). Oczywiście, można byłoby zoptymalizować serwer, żeby od
razu pytał o wszystko co się da, a potem wybierał najlepszą odpowiedź… ale
czy wysyłanie masy niepotrzebnych pakietów na pewno jest rozwiązaniem?

Informacje jak skonfigurować serwer do prawidłowej obsługi rekordów SRV
można znaleźć we wpisie
u smoka i komentarzach do niego
. O tym, jak taki rekord SRV powinien
wyglądać, też informacji w sieci nie brakuje. Ja tylko opiszę najprostszy
przypadek:

Jeśli Twój serwer jabbera, obsługujący domenę domena.org
(JIDy postaci: użytkownik@domena.org, działa na maszynie
serwer.domena.org o adresie 1.2.3.4, to potrzebujesz
następujących wpisów w DNS (pierwszy zapewne już masz):

serwer.domena.org.     IN  A   1.2.3.4
_xmpp-server._tcp.domena.org.            IN  SRV 0 0 5269 serwer.domena.org.
_xmpp-client._tcp.domena.org.            IN  SRV 0 0 5222 serwer.domena.org.

Znaczenia cyferek nie będę tu opisywał, kto będzie chciał, ten znajdzie.
Podobne wpisy ‚_xmpp-server’ powinny być dla każdej domeny obsługiwanej przez
serwer, która ma być dostępna z zewnątrz. Poprawność wpisów należy oczywiście
sprawdzić, np. w ten sposób:

$ host -t SRV _xmpp-server._tcp.jajcus.net
_xmpp-server._tcp.jajcus.net SRV 10 0 5269 tropek.jajcus.net.
$ host -t SRV _xmpp-client._tcp.jajcus.net
_xmpp-client._tcp.jajcus.net SRV 10 0 5222 tropek.jajcus.net.
$ host -t SRV _xmpp-server._tcp.gg.jajcus.net
_xmpp-server._tcp.gg.jajcus.net SRV 10 0 5269 tropek.jajcus.net.

Migracja

Wynoszę się z firmy, w której stoi mój dotychczasowy serwer Jabbera. Chcąc
się od niej całkiem uniezależnić zmuszony byłem zmienić i JIDa. Od kilku dni więc
szykowałem swój nowy serwerek, a od wczoraj zacząłem uzupełniać CJC o funkcje ułatwiające migrację.

Nowe ficzery to polecenia:

/export_roster
Eksportuje roster do pliku XML.
/import_roster
Importuje roster z pliku XML – dodaje do rostera wpisy z pliku,
których w rosterze jeszcze nie było i wysyła prośby o subskrypcję dla wpisów
które w pliku mają subskrypcję to lub both.
/multi_message
Wysyła wiadomość jednocześnie do wielu użytkowników z rostera,
wybranych filtrem podobnym do tego używanego przez /list

Dzisiaj wypróbowałem nowe funkcje w warunkach bojowych. Wyeksportowałem
roster na starym koncie, wysłałem wiadomość o zmianie JIDa do wszystkich
kontaktów z subskrypcją from lub both i zaimportowałem roster na
nowym koncie. W ciągu pierwszej minuty od tej operacji dostałem około 50 próśb
o autoryzację – nigdy wcześniej nie widziałem tylu otwartych
zakładek w CJC %-).

W samą migrację nie chciałem mieszać transportów i botów, więc wcześniej
zrobiłem z tym porządki – wywaliłem transport ICQ, przeniosłem ręcznie
te kilka kontaktów na GG, zmieniłem JIDa w Joggerze. Tylko jeden bot się
odezwał na to moje /multi_message, ale chyba nic nie
narozrabiałem. W ogóle cała ta migracja przeszła coś naspodziewanie gładko…
zobaczymy co będzie dalej.

Jak jeszcze będzie mi się chciało, to zrobię sobie jeszcze małego bocika,
który będzie zalogowany na stare konto i będzie mi forwardował wiadomości na
nowe. Jak nie, to będę co jakiś czas logował się ręcznie i patrzył co się tam
dzieje. Dorobienie obsługi wielu kont do CJC, to byłoby stanowczo za dużo
roboty.

Dzięki ci, Google :-)

Hal Rottenberg rzucił na listę jdev linka do
odkrycia ralphma.
Oczywiście zaraz sprawdziłem u siebie:

[18:12] jajcus@gmail.com accepted your presence subscription request
[18:12] jajcus@gmail.com/CJC () is online:
[18:12] jajcus@gmail.com/CJC () is online:
[18:12] You have accepted presence subscription request from jajcus@gmail.com

No to Google się włączył na dobre do naszej wielkiej Jabberowej sieci
:-). No i kto nam teraz podskoczy ;-)

Wiem, że to właściwie niewiele znaczy, bo ten GTalk wcale taki popularny
nie jest… ale to jednak największy gracz który się włączył do federacji
serwerów XMPP i wiadomo, że będzie walczył o przyłączenie innych operatorów
IM. No i wielu wątpiło w to, że Google otworzy S2S, a jednak otworzyli i to
w miarę szybko.

Upgrade

Wczoraj ejabberd zaczął mi
szaleć. Nic z serwera nie przychodziło, to co się pisało szło efektywnie do
/dev/null, a nowe połączenia były odrzucane. Po restarcie zaczęło
działać, ale po godzinie znowu się zepsuło, tak samo.

Na serwerze miałem zainstalowanego dość starego Erlanga
(R9C-2) jak i samego ejabberd (0.7.5). Skoro działało, to po
co zmieniać. Jednak, gdy zaczęły się problemy, to aż głupio byłoby szukać
supportu do takich wykopalisk. Postanowiłem więc zrobić upgrade, ale bałem się.
Skok o kilka wersji przecież nie może przejść bezboleśnie.

Wczoraj wieczorem przygotowałem paczki PLD z najnowszym
Erlangiem i ejabberd. Poszło gładko, tylko
jeden mały patch był potrzebny. Ostatnim razem gdy próbowałem było gorzej,
w szczególności wychodziły jakieś problemy na AMD64. Dzisiaj postanowiłem te
nowe paczki zainstalować na serwerze. Przy okazji postanowiłem wypróbować
opcję --repackage RPMa, żeby mieć do czego wrócić, jak coś
pójdzie nie tak.

[root@serwus RPMS]# /etc/rc.d/init.d/ejabberd stop
Stopping ejabberd service..........................................[ DONE ]
[root@serwus RPMS]# rpm --repackage -Uvh erlang-R10B_7-0.1.amd64.rpm ejabberd-0.9.8-1.amd64.rpm
Preparing...                ########################################### [100%]
Repackaging...
   1:erlang                 ########################################### [ 50%]
   2:ejabberd               ########################################### [100%]
Upgrading...
   1:erlang                 ########################################### [ 50%]
   2:ejabberd               warning: /etc/jabber/ejabberd.cfg created as /etc/jabber/ejabberd.cfg.rpmnew
########################################### [100%]
Updating component authentication secret in ejabberd config file...
Generating erl authentication cookie...
Run "/etc/rc.d/init.d/ejabberd start" to start ejabberd server.
[root@serwus RPMS]# /etc/rc.d/init.d/ejabberd start
Starting ejabberd service..........................................[ DONE ]

Niemożliwe. To nie mogło być takie proste. A jednak, wygląda na to, że działa. Hmmm…