Posilani UDP na closed port

Dan Lukes dan at obluda.cz
Tue Jul 26 17:46:25 CEST 2005


Rudolf Cejka napsal/wrote, On 07/26/05 16:57:
> Ja s tim problem nemam ani ve FreeBSD, ani v Linuxu. Kdyz delam
> send(1) + recv(), chyba se vraci u recv(). Kdyz udelam
> send(1) + send(2) + recv(), chyba se vraci typicky u send(2) pro
> localhost a u recv() pro ostatni.

	Implementace v jadre je takova, ze dosle ICMP UNREACH_PORT se priradi 
(zkusi priradit) nejakemu otevrenemu conectnutemu socketu - a pokud jest 
takovy nalezen, zaznamena do relevantni struktury so_error=ECONREFUSED.

	Funkce send(), recv() hodnotu testuji a pokud je nenulova, pak bez 
dalsiho velkeho proceseni proste a jednoduse vrati tuto hodnotu jako 
svoji navratovou, cimz asynchronne detekovanou chybu predaji aplikaci (a 
zaznam o ni ve strukture vymazou).

	To znamena, ze chybu vrati nasledujici send/recv po zpracovani ICMP (a 
ktery to bude konretne zalezi na tom, jak rychle to ICMP prijde a je 
zpracovano).

	Zvlastni zpusob, jak zjistit zda je pro socket evidovana asynchronni 
chyba je volani getsockopt(,,SO_ERROR,,). Coz je popsano v manualove 
strance.

Radim Kolar napsal/wrote, On 07/26/05 16:14:
 >> 	Kdyz si clovek vybere funkce, ktere chybu nevraci, nemelo by ho
 >> 	zaskocit, ze ji nevraci ...
 > predelal jsem to na connect + send a send opravdu nevraci chybu jak v 
 > manualu pisi a to ani kdyz se posle UDP packet na closed port
 > opakovane.

	Mozna vysvetleni jsou dve - nejaky preklad/firewall po ceste zabrani 
prichodu prislusneho ICMP, nebo jeho obsah poskodi (nebo naopak 
nemodifikuje) a ten neni pak mozne priradit zadne probihajici komunikaci.

	No a jako druhou, pravdepodobnejsi moznost, vidim to, ze jste proste 
sendto() volane ve smycce nahradil dvojici connect()/send volanou ve smycce.

	Hacek je, ze novy connect() zaznam o asynchronni chybe rusi - coz je 
celkem logicke, protoze ta se tykala jine konexe. Takze jestli volate 
stridave connect a send, tak je jasne, ze ECONREFUSED neuvidite nikdy.

	Mozna by stalo za uvahu rozmyslet si jeste jednou a opatrne, co vlastne 
delate a ceho chcete dosahnout.

sendto() je urceno k odesilani jednotlivych paketu, jejichz osud a 
doruceni nas nezajima (ledaze to resime na aplikacni vrstve)

connect()+send() je urceno k navazovani spojeni, kdy nam nektere 
informace o tomto spojeni poskytuje sam system - dela to ale samozrejme 
jen do uzavreni daneho spojeni maje zato, ze po uzavreni spojeni nas o 
nem uz nic nezajima. Zbyva dodat, ze novy connect() na otevreny socket 
znamena implicitni uzavreni predchoziho spojeni.

	Takze si ujasnete (vy nebo autor kodu, pokud je to nekdo jiny), nakolik 
vas osud odeslaneho paketu zajima - a podle vysledku uvahy je nutne 
upravit logiku dotceneho programu. Nelze soucasne systemu rict, ze vas 
dane spojeni dale nezajima a soucasne byt nespokojen, ze vam o nem 
nasledne zadne udaje neposkytuje.

> S pozdravem rychlou smrt BSD stacku,

	Pri vsi ucte, troufam si tvrdit, ze reseny problem neni nedostatek BSD 
stacku, ale aplikace, ktera jest nad nim napsana, respektive, 
nezkusenost ci neznalost autora te aplikace, protoze aplikace jako 
takova samozrejme za nic nemuze.

	Ledaze za vec muze prve zmineny firewall ci preklad - ale i v tom 
pripade by v tom sitovy stack byl nevinne.

	Ja bych se, pri hledani chyb, podival nejprve do vlastnich rad a pak 
teprve hledal u sousedu ...

	Treba vam toto trochu obsahlejsi vysvetleni pomuze dosahnout toho, 
abyste ECONREFUSED konecne uvidel ... ;-)

					Zdravi

						Dan


-- 
Dan Lukes                                   SISAL MFF UK
AKA: dan at obluda.cz, dan at freebsd.cz,dan at kolej.mff.cuni.cz



More information about the Users-l mailing list