Microsoft Outlook troubleshooting
Zdarzenia SMTP w procesie przetwarzania wiadomości przez serwer SMTP (cz.I)

Zdarzenia SMTP w procesie przetwarzania wiadomości przez serwer SMTP (cz.I)

autor CodeTwo 2006-05-04 00:00:00 w Exchange Server

Artykuł dotyczy:

- Windows SMTP Server 2000/2003
- Exchange Server 2000/2003


Spis treści:

Wstęp
Proces przetwarzania wiadomości przez serwer SMTP i związane z nim zdarzenia
Rejestracja odbiorców zdarzeń
Odbiorcy zdarzeń implementowani przez Exchange Server
Podsumowanie



W artykule przedstawiono proces przetwarzania wiadomości w serwerze SMTP oraz związany z nim mechanizm zdarzeń. Opisano również komponenty serwera Exchange, które wykorzystują zdarzenia serwera SMTP w celu rozszerzenia jego funkcjonalności i zrealizowania funkcji specyficznych dla Exchange Server'a.

Wstęp

Zdarzenia SMTP są mechanizmem umożliwiającym rozszerzanie serwera SMTP będącego składnikiem systemu Windows 2000/XP/2003 i dostosowywanie go do konkretnych potrzeb organizacji. Idea zdarzeń opiera się na źródle zdarzenia i odbiorcy. W określonych okolicznościach źródło informuje odbiorcę o zajściu pewnego zdarzenia. Źródłem jest tutaj serwer SMTP, natomiast odbiorcą komponent COM implementujący odpowiednie interfejsy programowe. Podczas przetwarzania wiadomości e-mail serwer SMTP generuje całą serię zdarzeń związanych ze stanem, w jakim obecnie znajduje się konkretna wiadomość. Zdarzenia te rozsyłane są do tych odbiorców, którzy się na nie zarejestrowali, pozwalając im reagować na proces przetwarzania wiadomości, rozszerzać go lub modyfikować. Typowe funkcje implementowane przez odbiorców zdarzeń, to:

- dodawanie sygnatury do wiadomości wychodzących z organizacji,
- skanowanie przychodzących maili w celu wykrycia wirusów lub spamu,
- zapisywanie wszystkich maili przesyłanych przez serwer, np. w celach archiwizacyjnych,
- odrzucanie maili wysłanych z określonych adresów, czy na określone adresy,
- rozszerzenie protokołu komunikacyjnego SMTP.


O tym jak duże możliwości dają zdarzenia SMTP, może świadczyć choćby fakt, że są one głównym mechanizmem wykorzystywanym przez serwer Exchange w rozszerzaniu funkcjonalności serwera SMTP. Podczas instalacji serwer Exchange rejestruje grupę własnych odbiorców zdarzeń, realizujących jego podstawowe funkcje. Oto kilka funkcji Exchange realizowanych właśnie za pomocą odbiorców zdarzeń:

- kategoryzowanie wiadomości i rozwijanie list dystrybucyjnych na podstawie danych zapisanych w Active Directory,
- sprawdzanie limitów wiadomości,
- określanie trasy przesyłania e-maili,
- zapisywanie wiadomości we własnym magazynie informacji,
- rozszerzanie protokołu SMTP,
- śledzenie przetwarzanej wiadomości.


Instalacja Exchange serwera w żaden sposób nie ogranicza możliwości implementacji kolejnych odbiorców zdarzeń, a co za tym idzie dalszego rozszerzania serwera SMTP oraz samego Exchange serwera. Architektura zdarzeń zostaje niezmieniona pozwalając nam implementować zupełnie nowe rozszerzenia i realizować własne pomysły.


Proces przetwarzania wiadomości przez serwer SMTP i związane z nim zdarzenia

Generalnie proces odbierania/wysyłania wiadomości w serwerze SMTP przebiega następująco:

1. Moduł protokołu SMTP serwera odbiera wiadomość od zdalnego serwera SMTP lub klienta pocztowego. Komunikacja pomiędzy obydwoma stacjami odbywa się za pomocą protokółu SMTP.
2. Po odebraniu wiadomość zostaje dostarczona do modułu transportowego serwera (Advanced Queueing Engine). Tutaj komponent odpowiedzialny za kategoryzację tzw. kategoryzator (Categorizer) ustala, czy odbiorcy wiadomości mają skrzynki na lokalnym serwerze.
3. Jeśli istnieją lokalni odbiorcy to wiadomości jest dostarczana do ich skrzynek, jeśli nie, to jest wstawiana do kolejki wiadomości wychodzących.
4. Moduł protokołu SMTP serwera pobiera wiadomości z kolejki wiadomości wychodzących i wysyła je do zdalnych serwerów SMTP.


Podczas przetwarzania wiadomości przez serwer, generowane są różne zdarzenia związane ze stanem, w jakim się ona obecnie znajduje. Za rozsyłanie zdarzeń do zarejestrowanych odbiorców odpowiedzialny jest specjalny moduł serwera SMTP zwany Dispatcher'em. Serwer kontynuuje przetwarzanie wiadomości dopiero, gdy dane zdarzenie zostanie przetworzone przez wszystkich odbiorców. Naturalnie nasuwa się tu pytanie o wydajność serwera - jeśli zdarzenie jest wysyłane do wszystkich odbiorców, a serwer kontynuuje pracę dopiero gdy wszyscy odbiorcy je przetworzą, to czy nie wpływa to negatywnie na szybkość działania serwera? Otóż niekoniecznie, projektanci systemu założyli, że odbiorca zdarzeń powinien otrzymywać powiadomienia nie o każdym ze zdarzeń, a jedynie o tych, na które się zarejestrował. Kolejność, w jakiej odbiorcy są powiadamiani o zdarzeniu, zależy od priorytetu, z jakim zostali zarejestrowani. Przy takim podejściu i odrobinie wyczucia przy programowaniu odbiorców, można zredukować niebezpieczeństwo niekontrolowanego spadku wydajności serwera.

Zdarzenia generowane przez serwer SMTP dzieli się na dwie grupy: zdarzenia protokołu SMTP oraz zdarzenia modułu transportowego.

Zdarzenia protokołu SMTP są rozsyłane do odbiorców, gdy serwer komunikuje się i przeprowadza transmisję SMTP ze zdalnym serwerem lub klientem pocztowym w celu odebrania lub wysłania wiadomości. Zdarzenia generowane podczas odbierania wiadomości noszą nazwę OnInboundCommand, natomiast zdarzenia generowane podczas wysyłania wiadomości to OnOutboundCommand oraz OnServerResponse.

Zdarzenia transportowe są generowane już po zakończeniu transmisji SMTP podczas przetwarzania wiadomości przez moduł transportowy serwera. Należą do nich: OnSubmission, OnPreCategorize, OnPostCategorize, OnMaxMsgSize, OnMsgTrackLog, OnEventLog. Dodatkowo istnieje kilka zdarzeń transportowych określanych mianem zdarzeń komponentów systemu, a to ze względu na to, że ich odbiorcy implementują ważne funkcje systemowe, gwarantujące poprawne działanie warstwy transportu wiadomości. Zaliczamy do nich: OnCategorize, OnGetMessageRouter, StoreDriver, OnDnsResolveRecord

W celu rozjaśnienia tej nieco zagmatwanej hierarchii zdarzeń, przedstawiam poniżej rysunek obrazujący proces przepływu wiadomości w serwerze SMTP oraz towarzyszące mu zdarzenia generowane podczas przetwarzania wiadomości. Czarnymi strzałkami zaznaczony został przepływ wiadomości przez serwer SMTP, czerwonymi - zdarzenia generowane podczas przetwarzania wiadomości. Niebieskie prostokąty to ważni odbiorcy zdarzeń niezbędni w serwerze SMTP i pełniący rolę komponentów systemowych serwera SMTP.

Przepływ wiadomości w serwerze SMTP i generowane zdarzenia
rys.1 Przepływ wiadomości w serwerze SMTP i generowane zdarzenia


Podczas odbierania wiadomości od zdalnego serwera SMTP lub klienta pocztowego generowane jest zdarzenie dla każdej komendy protokołu SMTP odebranej przez serwer (np. EHLO, MAIL FROM, RCPT TO, DATA). Jak już wyżej wspomniano, zdarzenia dla przychodzących komend SMTP określa się wspólną nazwą OnInboundCommand. Odbiorca rejestrujący się na to zdarzenie, może dokładnie określić, dla jakich komend protokołu SMTP chce otrzymywać powiadomienie. Mechanizm ten umożliwia programiście praktycznie nieograniczoną kontrolę nad tym, w jaki sposób przebiega komunikacja protokołem SMTP. Zdarzenia generowane dla przychodzących komend można wykorzystać na przykład do rozszerzania protokołu o nowe komendy, modyfikowania działania obecnych komend, czy do skanowania zawartości wiadomości.

Po zakończeniu transmisji SMTP i odebraniu wiadomości przez serwer jest ona przekazywana do modułu transportowego serwera oraz umieszczana w kolejce pre-submission queue. Po wstawieniu wiadomości do kolejki generowane jest zdarzenie OnSubmission, a dispatcher modułu transportowego rozsyła je do wszystkich zarejestrowanych odbiorców.

Jeśli wszyscy odbiorcy odpowiedzieli pozytywnie na zdarzenie OnSubmission, wiadomość jest przenoszona do kolejki pre-categorization queue oraz generowane i rozsyłane jest zdarzenie OnPreCategorize. W tym momencie rozpoczyna się proces kategoryzacji, którego głównym zadaniem jest rozwinięcie grup dystrybucyjnych i określenie, czy odbiorcy wiadomości posiadają skrzynki na lokalnym serwerze i czy w związku z tym wiadomość powinna zostać dostarczona lokalnie, czy też przesłana do kolejnego zdalnego serwera. Podczas kategoryzacji generowane jest jedno z najważniejszych zdarzeń w całym procesie przetwarzania wiadomości: OnCategorize. Dokładnie rzecz ujmując nie jest ono pojedynczym zdarzeniem, lecz ciągiem zdarzeń, które muszą być obsłużone w celu poprawnej kategoryzacji wiadomości. Komponent, który je obsługuje nazywany jest kategoryzatorem i przypisuje do wiadomości odpowiednie atrybuty, wykorzystywane później przez inne komponenty w dalszym procesie obróbki wiadomości.

Po zdarzeniach OnCategorize może zostać wygenerowane zdarzenie OnMaxMsgSize, jeśli wiadomość przekracza obecnie zdefiniowany limit. Odbiorca, który obsłuży to zdarzenie może zezwolić na przesyłanie wiadomości nawet, jeśli mają zbyt duży rozmiar.

Gdy proces kategoryzacji jest zakończony, rozsyłane jest zdarzenie OnPostCategorize, a wiadomość jest umieszczana w kolejce pre-routing queue.

Wiadomości pobierane są z tej kolejki i na podstawie atrybutów utworzonych podczas kategoryzacji wiadomości i na ich podstawie podejmowana jest decyzja czy wiadomość ma zostać dostarczona lokalnie, czy wysłana do zdalnego serwera SMTP. Wiadomości lokalne przekazywane są do kolejki lokalnego dostarczania (local delivery queue) skąd zostaną pobrane i umieszczone w skrzynkach użytkowników przez komponent store driver. Dla wiadomości, które muszą zostać przesłane dalej do zewnętrznych serwerów generowane są zdarzenia kategorii OnGetMessageRouter. Zdarzenia te są obsługiwane przez router - moduł odpowiedzialny za wyznaczenie nowej trasy wiadomości, a dokładnie jej następnego miejsca docelowego (next hop), do którego zostanie przesłana tak, aby mogła trafić do odbiorcy. Po określeniu tego miejsca wiadomość zostaje przesłana do kolejki wychodzących wiadomości (remote delivery queue); przedtem jednak generowane jest jeszcze jedno zdarzenie transportowe OnDnsResolveRecord. Pozwala ono na przetłumaczenie nazwy domenowej miejsca docelowego na adres IP.

Wiadomości z kolejek wychodzących pobierane są przez moduł protokołu SMTP i wysyłane są do zdalnych serwerów. Podczas wysyłania wiadomości dla każdej komendy generowane jest zdarzenie OnOutboundCommand. Jednocześnie przy każdej odpowiedzi serwera zdalnego generowane jest zdarzenie OnServerResponse. Odbiorcy tych zdarzeń podobnie jak miało to miejsce przy zdarzeniach OnInboundCommand, mogą rozszerzać i kontrolować zachowanie komend SMTP. W rzeczywistości OnOutboundCommand jest ogólną nazwą kilku zdarzeń generowanych dla różnych komend SMTP wysyłanych przez serwer lokalny. I tak przy wysyłaniu komendy EHLO generowane jest zdarzenie OnSessionStart, dla komendy MAIL FROM generowane jest zdarzenie OnMessageStart, dla RCPT TO - OnPerRecipient, dla DATA - OnBeforeData, dla QUIT - OnSessionEnd.

W ciągu całego procesu przetwarzania wiadomości przez moduł transportowy generowane są zdarzenia OnMsgTrackLog i OnEventLog. Są ono wołane bardzo często i pozwalają śledzić przebieg wiadomości oraz kolejne kroki przetwarzania wykonywane w module transportowym.

Kolejną ważną kategorią zdarzeń są zdarzenia StoreDriver. Implementuje je odbiorca (store driver) odpowiedzialny za dostarczenie i obsługę fizycznej postaci wiadomości podczas jej przetwarzania przez serwer SMTP. Wołany jest on za każdym razem, gdy musi zostać stworzony lub trwale zapisany obiekt reprezentujący wiadomość. Ten obiekt to tzw. MailMsg, który implementuje zestaw określonych interfejsów umożliwiających czytanie zawartości obiektu oraz wprowadzanie w nim zmian. Jest on przechowywany przez store driver'a, a referencja do niego przekazywana jest pomiędzy kolejnymi komponentami i odbiorcami przetwarzającymi wiadomość. W przypadku wiadomości SMTP obiekt MailMsg przechowuje jej fizyczną reprezentację oraz dodatkowe informacje dodawane do niej podczas przetwarzania, np. przez kategoryzator czy przez router. Zdarzenia StoreDriver generowane są podczas odbierania wiadomości od zdalnego serwera, podczas tworzenia obiektu MailMsg, który jak wspomniano będzie reprezentował wiadomość. Obiekt ten jest również tworzony, gdy zażąda tego kategoryzator podczas tworzenia kopii wiadomości. W czasie dostarczania wiadomości do lokalnej skrzynki użytkownika store driver ma za zadanie trwale zapisać obiekt MailMsg, np. na dysku, natomiast podczas wysyłania wiadomości na zewnątrz store driver jest o tym informowany, aby mógł usunąć obiekt MailMsg. W przypadku standardowego serwera SMTP systemu Windows store driver'em jest NTFS Driver, który zapisuje wiadomości w systemie plików w postaci plików EML. Exchange Server instaluje dodatkowo własnego store driver'a (Exchange store driver), który przechowuje wiadomości w bazie danych Exchange Information Store.

Należy tu zaznaczyć, że przedstawiony proces dotyczy przetwarzania wiadomości SMTP odbieranych od zdalnych serwerów SMTP lub klientów pocztowych. Wygląda on inaczej w przypadku wiadomości wysyłanych z klientów MAPI, Outlook Web Access, konektorów X400, czy konektorów dla Lotus Notes, ponieważ wtedy w procesie przetwarzania wiadomości uczestniczy agent Exchange MTA (Exchange Message Transfer Agent). Zajmiemy się nim w kolejnym artykule dotyczącym zdarzeń SMTP.


Rejestracja odbiorców zdarzeń

Aby odbiorca był powiadamiany o zdarzeniach serwera SMTP musi zarejestrować się w metabazie IIS poprzez dokonanie specjalnego wpisu. Odbiorca zdarzeń to komponent COM, które implementuje odpowiednie interfejsy w zależności od tego, na jakie zdarzenie się zarejestrował. Na przykład komponent, który chce odbierać zdarzenia o przychodzących komendach SMTP rejestruje się na zdarzenie OnInboundCommand i implementuje interfejs ISmtpInCommandSink. Interfejs ten ma tylko jedną funkcję OnSmtpInCommand, która jest wołana przez dispatcher'a zdarzeń za każdym razem, gdy serwer otrzymuje komendę SMTP. Argumentami funkcji są obiekty zawierające dane o lokalnym serwerze SMTP, obecnej sesji SMTP, obecnej komendzie SMTP oraz referencję do obiektu MailMsg, który reprezentuje odbieraną wiadomość. Korzystając z tych obiektów komponent ma możliwość reagowania na poszczególne komendy i ingerowania w odpowiedzi serwera SMTP. Podczas rejestracji odbiorca zdarzeń może określić dwa parametry. Pierwszy z nich to priorytet odbiorcy, który określa, w jakiej kolejności odbiorcy zarejestrowani dla tego zdarzenia są o nim powiadamiani. Odbiorca, który zarejestruje się z wyższym priorytetem jest powiadamiany wcześniej. Drugim parametrem jest reguła, która dodatkowo określa, dla jakich komend SMTP odbiorca powinien być powiadamiany o zdarzeniu. Korzystając z powyższego przykładu odbiorca zarejestrowany na zdarzenie OnInboundCommand może określić następującą regułę:

MAIL FROM=*@codetwo.pl

Oznacza ona, że będzie powiadamiany o zdarzeniu tylko dla komendy MAIL FROM, która zawiera w adresie nadawcy domenę outlook.pl. Reguła może określać kilka warunków, np.:

MAIL FROM=*@codetwo.pl; RCPT TO=*wss.pl

Specjalnym typem reguły jest reguła _EOD (End of Data). Oznacza ona, że do odbiorcy zostanie wysłane zdarzenie związane z końcem odbierania danych przez lokalny serwer. W tym momencie obiekt MailMsg zawiera już cała wiadomość, dlatego reguły tej często używają programy antywirusowe skanujące przychodzące wiadomości. Jeśli odbiorca nie ustawi żadnej reguły będzie powiadamiany o wszystkich zdarzeniach danego typu bez dodatkowego filtrowania. Reguły można definiować dla zdarzeń protokołu SMTP oraz dla zdarzeń transportowych: OnSubmission, OnPreCategorize, OnPostCategorize.

Rejestrowanie się odbiorcy na zdarzenie w metabazie IIS nazywane jest wiązaniem. Wiązanie to określa, dla jakiego zdarzenia SMTP i w jakich warunkach oraz jaki obiekt COM powinien być powiadamiany o zdarzeniu. Wiązanie zawiera następujące dane:

- zdarzenie - identyfikowane jest poprzez określony GUID, który jest odpowiednikiem nazwy zdarzenia. Na przykład zdarzenie OnSubmission identyfikowane jest przez GUID FF3CAA23-00B9-11d2-9DFB-00C04FA322BA,
- nazwę klasy obiektu COM, którą odbiorca implementuje. Na jej podstawie dispatcher zdarzeń może zainstancjować obiekt odbiorcy,
- dowolną nazwę zrozumiała dla człowieka opisującą wiązanie. Ma ona funkcję pomocniczą i pozwala szybko zidentyfikować wiązanie,
- dodatkowe argumenty dla źródła zdarzenia, czyli priorytet i reguła, oba są opcjonalne. Jeśli odbiorca nie poda swojego priorytetu przypisywany jest mu priorytet domyślny (liczba 24575).


Aby dokonać wpisu w metabazie należy użyć edytora metabazy MetaEdit, albo skorzystać z obiektów COM o nazwie SEO przeznaczonych do edycji metabazy. Microsoft opublikował specjalny skrypt smtpreg.vbs (można go pobrać z witryny MSDN lub z adresu https://www.outlook.pl/downloads/smtpreg.vbs), który używa obiektów SEO właśnie do rejestracji odbiorców zdarzeń SMTP. Skryptu możemy użyć również w celu przeglądnięcia wszystkich zarejestrowanych odbiorców zdarzeń. Wystarczy uruchomić go z parametrem /enum i skierować wynik do pliku:

smtpreg.vbs /enum > bindings.txt

Pierwsza część pliku tekstowego bindings.txt wyświetla wszystkie dostępne zdarzenia STMP, są to sekcje oznaczone jako Event Type. Dla Exchange 2000 w pliku bindings.txt nie znajdziemy zdarzeń OnMessageStart, OnSessionEnd, OnServerResponse na podstawie ich nazw, ponieważ Exchange Server zamienia je na "X-LSA outbound protocol event" (dla dwóch pierwszych) oraz "EHLO server response protocol event for X-LSA" dla OnServerResponse. Nic to jednak nie zmienia, ponieważ w wiązaniach zdarzenia i tak są identyfikowane przez ich przypisane im wartości GUID.

Druga część pliku w sekcjach oznaczonych jako Binding pokazuje wszystkie dostępne wiązania pomiędzy odbiorcami zdarzeń a zdarzeniami. Na przykład sekcja:

-----------
| Binding |
-----------
    Event: SMTP Transport OnCategorize
    ID: {5644CD31-2014-11D2-9E03-00C04FA322BA}
    Name: Exchange Categorizer
    SinkClass: Exchange.Categorizer
    Enabled: True
    SourceProperties: {
                         priority = 8192
                      }

przedstawia kategoryzatora serwera Exchange. Na podstawie pola ID możemy stwierdzić, że zarejestrowany jest on na zdarzenia OnCategorize. Komponent COM, który go implementuje ma klasę Exchange.Categorizer i zainstalowany jest z wysokim priorytetem 8192. Priorytet najwyższy to 0, najniższy to 32767 (domyślny to 24575). Po sprawdzeniu nazwy klasy przeszukując rejestr możemy dowiedzieć się, że klasa Exchange.Categorizer jest implementowana przez obiekt COM w bibliotece \ExchSrvr\bin\phatcat.dll.

Natomiast sekcja:

---------
| Binding |
---------
    Event: SMTP Inbound command protocol event
    ID: {B8AE826A-DB15-11D2-9500-00C04F79F1D6}
    Name: Exchange SMTP Protocol XEXCH50 Inbound Ehlo Sink
    SinkClass: peexch50.ehlo
    Enabled: True
    SourceProperties: {
                         priority = 30000
                         rule = EHLO
                      }

przedstawia komponent serwera Exchange zarejestrowany na zdarzenie OnInboundCommand. Ustawiona jest tu reguła EHLO, co oznacza, że odbiorca będzie powiadamiany o zdarzeniu tylko w momencie, gdy serwer zdalny lub klient pocztowy wyśle do lokalnego serwera komendę EHLO. Obiekt COM implementujący klasę peexch50.ehlo znajduje się w bibliotece \ExchSrvr\bin\peexch50.dll.

Wiązania z pliku bindings.txt znajdziemy w metabazie IIS w gałęzi \LM\SMTPSVC\1\EventManager\EventTypes:

Wiązania odbiorców zdarzeń w metabazie IIS
rys.2 Wiązania odbiorców zdarzeń w metabazie IIS


Baza wiązań jest utrzymywana osobno dla każdego wirtualnego serwera SMTP.

W pliku bindings.txt możemy znaleźć także definicje zdarzeń i wiązania zarejestrowane dla serwera NNTP. Serwer ten podobnie jak serwer SMTP posiada mechanizm zdarzeń i udostępnia trzy zdarzenia: OnPostEarly, OnPost, OnPostFinal.


Odbiorcy zdarzeń implementowani przez Exchange Server

Przeglądając wiązania z pliku bindings.txt możemy zauważyć jakie komponenty odbiorców zdarzeń instaluje serwer Exchange w celu rozszerzenia funkcjonalności standardowego serwera SMTP. Serwer Exchange instaluje komponenty, które implementują bardziej zaawansowaną i wydajną obsługę poczty i ruchu w sieci zawierającej wiele serwerów Exchange podzielonych na tzw. grupy routowania (routing groups).

Exchange wprowadza trzy nowe komendy SMTP: XEEXCH50, X-LINK2STATE i X-EXPS. Do obsługi każdej z nich instalowany jest osobny komponent.

XEXCH50 jest komendą protokołu SMTP służącą do przesyłania rozszerzonych informacji o wysyłanej wiadomości pomiędzy serwerami Exchange. Aby je zaimplementować Exchange rejestruje swój komponent COM z biblioteki \ExchSrvr\bin\peexch50.dll dla 9 zdarzeń protokołu SMTP oraz dla jednego zdarzenia transportowego. Do zdarzeń protokołu SMTP zaliczamy:

- OnInboundCommand dla komend: EHLO, MAIL FROM, EXEXCH50, RCPT TO,
- OnServerResponse dla komendy: EHLO, RCPT TO, EXEXCH50,
- OnOutboundCommand: OnPerRecipient, OnBeforeData,
- Zdarzenie transportowe to: OnSubmission.


X-LINK2STATE jest komendą rozszerzającą protokół SMTP, przez którą serwery Exchange przesyłają między sobą informacje dotyczące dostępności serwerów wewnątrz i pomiędzy grupami routowania w celu możliwości obrania odpowiedniej trasy przesyłania wiadomości. Aby zaimplementować komendę Exchange rejestruje swój komponent COM z biblioteki \ExchSrvr\bin\xlsasink.dll dla 5 zdarzeń protokołu SMTP:

- OnInboundCommand dla komend: EHLO, X-LINK2STATE,
- OnServerResponse dla komend: EHLO, X-LINK2STATE,
- OnOutboundCommand: OnMessageStart


X-EXPS to rozszerzenie protokołu SMTP, które umożliwia bezpieczne łączenie się z serwerem Exchange poprzez uwierzytelnianie klienta. Implementowane jest przez komponent COM z biblioteki \ExchSrvr\bin\exps.dll, który rejestruje się na 5 zdarzeń protokołu SMTP:

- OnInboundCommand dla komend: X-EXPS, AUTH, _EOD,
- OnServerResponse dla komendy X-EXPS,
- OnOutboundCommand: OnSessionStart dla komendy X-EXPS


Exchange wykorzystuje także zdarzenie OnInboundCommand do wykrywania spamu. Zajmuje się tym komponent z biblioteki \ExchSrvr\bin\turflist.dll, który rejestruje się na zdarzenie OnInboundCommand dla 3 komend SMTP: MAIL FROM, RCPT TO, _EOD.

Exchange Server wykorzystuje zdarzenia transportowe, aby rozszerzyć i zmienić funkcjonalność serwera SMTP w warstwie transportowej. I tak instaluje własnego kategoryzatora, routera, load balancer'a, store driver'a oraz komponenty odpowiedzialne za logowanie przetwarzania wiadomości.

Kategoryzator dostarczany przez serwer Exchange jest jednym z najważniejszych komponentów w module transportowym serwera SMTP:

- Przede wszystkim przeszukuje Active Directory w celu określenia czy wiadomość powinna zostać dostarczona do lokalnych odbiorców.
- Rozwija grupy dystrybucyjne.
- Ustawia atrybuty obiektu MailMsg, które decydują o wygenerowaniu raportów NDR dla wiadomości. Przykładowo, gdy Exchange obsługuje domenę, dla której jest odpowiedzialny za obsługę całego dostarczania poczty (zaznaczona opcja "This Exchange Organization is responsible for all mail delivery to this address") i nie może znaleźć adresu należącego do domeny, ustawia na wiadomości atrybut, na podstawie którego później wygenerowany zostanie NDR 5.1.1. Jeśli określony jest serwer alternatywny, do którego powinny być kierowane wiadomości, dla których nie znaleziono odbiorców w domenie, to kategoryzator ustawi odpowiednie atrybuty, które spowodują, że wiadomość zostanie przesłana do takiego serwera
- Sprawdza limity ustawione dla wiadomości oraz jej nadawców i odbiorców, jeśli zostają przekroczone, ustawia odpowiednie atrybuty na obiekcie MailMsg.
- Określa, jaki format powinna mieć wiadomość przeznaczona dla danego nadawcy. W razie potrzeby powiela wiadomość. Typowym przykładem powielenia wiadomości jest sytuacja, gdy wiadomość w formacie MAPI musi zostać przekształcona na inny format aby mogła zostać wysłana do odbiorcy nie-MAPI.


Router Exchange Server'a odpowiedzialny jest za określenie następnego miejsca docelowego, do którego powinna zostać przesłana wiadomość, jeśli nie jest przeznaczona dla lokalnego odbiorcy. W organizacji Exchange może istnieć wiele grup routowania i wiele tras prowadzących do tego samego miejsca docelowego. Zadaniem komponentu routera jest wyznaczenie najkrótszej trasy o najniższym koszcie. Wyznaczanie trasy opiera się na informacji o topologii grupach routowania przechowywanej w Active Directory oraz informacji o dostępności połączeń, która wymieniana jest pomiędzy serwerami Exchange przy użyciu komendy X-LINK2STATE protokołu SMTP.

Jeśli w organizacji istnieje kilka tras prowadzących do tego samego miejsca docelowego i mają one taki sam koszt, to Exchange używa modułu load balancer, aby zdecydować, którą trasą powinna zostać przesłana wiadomość, aby równomiernie rozłożyć ruch w sieci.

Store driver Exchange Server'a jest odpowiedzialny za zarządzanie pamięcią dla obiektu MailMsg i za jego tworzenie. Musi także dostarczać go w odpowiednim formacie na żądanie kategoryzatora, np. gdy wiadomość wysłana w formacie MAPI musi zostać przekształcona na postać RFC 822, aby mogła zostać przesłana do zewnętrznego odbiorcy przez konektor SMTP. Gdy wiadomość musi zostać dostarczona do lokalnego użytkownika zadaniem store driver'a jest zapisane obiektu w bazie i przypisanie go do odpowiedniej skrzynki.

Exchange instaluje również własnych odbiorców zdarzeń, dzięki którym śledzi przetwarzanie wiadomości w module transportu oraz loguje wszystkie komendy protokołu SMTP.


Podsumowanie

W tej części artykułu opisany został mechanizm zdarzeń w serwerze SMTP systemu Windows. Przedstawiłem proces przetwarzania wiadomości przez serwer SMTP oraz związane z nim zdarzenia. Mogliśmy zobaczyć, w jaki sposób serwer Exchange wykorzystuje zdarzenia, aby zmienić i rozszerzyć funkcjonalność standardowego serwera SMTP i jak przy użyciu własnych komponentów (odbiorców zdarzeń) implementuje bardziej zaawansowane techniki przetwarzania wiadomości.

W następnej części artykułu napiszemy własnego prostego odbiorcę zdarzeń i zastanowimy się, dlaczego w niektórych przypadkach nie działa tak jak byśmy się tego spodziewali. W tym celu będziemy musieli przyjrzeć się bliżej przepływowi wiadomości przez moduł transportowy SMTP serwera Exchange.

Jeśli masz jakieś pytania lub komentarze dotyczące tego artykułu, napisz na naszym forum.

(c) CodeTwo. Wszelkie prawa zastrzeżone.



© Wszelkie prawa zastrzeżone. Żadna część ani całość tego artykułu nie może być powielana ani publikowana bez zgody autora.