setsockopt()
i getsockopt()
setsockopt()
i
getsockopt()
DEFINCJE: int setsockopt (int sockfd, int level, int optname, char *optval, int optlen) int getsockopt (int sockfd, int level, int optname, char *optval, int *optlen) WYNIK: 0 w przypadku powodzenia -1 gdy blad: errno = EBADF (argument sockfd nie jest poprawnym deskryptorem) ENOTSOCK (sockfd nie jest deskryptorem gniazda) ENOPROTOOPT (nieprawidlowa opcja na wskazanym poziomie) EFAULT (optval wskazuje na nieprawidlowy adres)Znaczenie argumentow jest nastepujace:
sockfd
- deskryptor
gniazda, level
- poziom, ktorego dotyczy opcja, mozliwe wartosci:
SOL_SOCKET
- nawyzszy poziom - ogolny program
obslugi gniazd, IPPROTO_xxx
- opcje protokolow,
optval
- wskaznik zmiennej uzytkownika, z ktorej pobierana jest
wartosc ustanawianej opcji (setsockopt) lub na ktora zapisuje sie wartosc
wybranej opcji (getsockopt),
optlen
- rozmiar zmiennej wskazywanej przez optval.
sock
posiada szereg pol o nazwach zblizonych do nazw odpowiednich
opcji, wiekszosc z nich to pola znacznikowe.
Przy tworzeniu gniazda pola te sa inicjalizowane domyslnymi wartosciami,
zas zmiany ich wartosci dokonuja funkcje: (plik net/core/sock.c
)
int sock_setsockopt(struct sock *sk, int level, int optname, char *optval, int optlen);oraz
int sock_getsockopt(struct sock *sk, int level, int optname, char *optval, int *optlen);
Ponizej wymienione sa wazniejsze opcje ustawiane za pomoca funkcji
set[get]sockopt()
UWAGA: Przy opcjach - znacznikach przyjeta nastepujaca konwencja: (optval != 0) oznacza "tak" , (optval == 0) oznacza "nie". Przy opcjch, ktorych nie mozna ustawiac (a tylko sprawdzac ich wartosci) widnieje napis ,,(tylko get)''.
Poziom interfejsu gniazd (level =
SOL_SOCKET)
SO_BROADCAST
SO_DEBUG
Wlacza / wylacza diagnostyke prowadzona na nizszych warstwach protokolow (polega ona na utrzymywaniu przez jadro historii ostatnio wyslanych i odebranych pakietow).
SO_DONTROUTE
Ustala, czy wysylane komunikaty moga omijac normalne mechanizmy wyboru trasy stosowane przez dany protokol.
SO_ERROR
(tylko get) Zwraca i zeruje status bledu dla gniazda.
SO_TYPE
(tylko get) Zwraca rodzaj gniazda. Mozliwosc sprawdzenia typu gniazda moze byc pozyteczna np. dla procesu, ktory dziedziczy deskryptor gniazda.
SO_KEEPALIVE
(tylko dla gniazd typu SOCK_STREAM) Umozliwia badanie stanu polaczenia za pomoca okresowych transmisji przez polaczone gniazdo. Jezeli druga strona polaczenia nie odpowiada na te komunikaty, to polaczenie uwaza sie za zerwane, zas procesy uzywajace gniazda otrzymuja sygnal SIGPIPE przy probie wyslania danych, a wartosc errno jest ustawiana na ETIMEDOUT.
SO_LINGER
(tylko dla gniazda typu SOCK_STREAM)
Okresla jakie czynnosci maja byc wykonywane w momencie
wywolania funkcji close, gdy pozostaly komunikaty czekajace
na wyslanie. Domyslnie funkcja close wykonuje natychmiastowy
powrot, a system probuje wyslac te dane.
Ustawienie opcji SO_LINGER wymaga przeslania do jadra
(w zmiennej optval) nastepujacej struktury (zdefiniowanej w
pliku include/linux/socket.h
:
struct linger { int l_onoff; /* Flaga logiczna: 0 = wlacz, !0 = wylacz */ int l_linger; /* Czas zwlekania (w sekundach) */ }Czas zwlekania rowny zero oznacza, ze przy zamknieciu gniazda jadro ma zignorowac niewyslane dane.
SO_DONTLINGER
Wylaczenie opcji linger.
SO_RCVBUF, SO_SNDBUF
Okreslenie rozmiarow buforow dla kolejek danych pobieranych
i wysylanych.
Ograniczenia na wielkosc tych buforow w Linuxie:
co najmniej 256 i co najwyzej 65536 bajtow
Domyslny rozmiar obu buforow okreslaja stale odpowiednio:
SK_RMEM_MAX
oraz SK_WMEM_MAX
,
ktore w zaleznosci od ustawienia flagi CONFIG_SKB_LARGE
przy kompilacji jadra maja jednakowe wartosci: 65536 lub
32767 bajty.
SO_REUSEADDR
Ustawienie tej opcji zezwala na ponowne wykorzystanie tego
samego numeru portu przez gniazdo bez koniecznosci odczekiwania czasu
okreslonego stala TCP_TIMEWAIT_LEN. Przy obecnosci tej opcji nadal gniazdo
zamkniete instrukcja close()
jest zachowywane w
strukturach jadra w stanie TIME_WAIT
, ale dozwolone jest
jego usuniecie przez przypisanie innemu gniazdu tego samego numeru portu.
Wiecej szczegolow - w opisie funkcji bind()
SO_OOBINLINE
Oznacza, ze dane wysokopriorytetowe maja byc umieszczane w
normalnej kolejce danych wejsciowych. Wowczas nie jest wymagany znacznik
MSG_OOB
w funkcjach pobierania danych.
Poziom protokolow
(level = IPPROTO_TCP)
TCP_MAXSEG
(tylko get) Sprawdzenie maksymalnego rozmiaru segmentu, jakiego moze uzyc gniazdo.
TCP_NODELAY
Ustawienie tej opcji wylacza grupowanie pakietow wysylanych przez warstwe TCP (Nagle buffering algorithm). Przydatne jedynie gdy wysylamy czesto male ilosci danych bez potrzeby natychmiastowego potwierdzenia kazdego komunikatu (np. wysylanie przez klienta informacji za posrednictwem myszki z terminala ,,okienkowego'').
(level = IPPROTO_IP)
IP_OPTIONS
Pozwala ustalic / odczytac opcje w naglowku IP komunikatow wysylanych przez
gniazdo. Opcje te zapisane sa w parametrze optval
. Mozliwosc ta wymaga znajomosci budowy naglowka IP (patrz: Temat 8, rozdzialy o IP).
Oprocz omowionych powyzej funkcji setsockopt()
i
getsockopet()
, specjalnie zaprojektowanych do
manipulowania opcjami, konfigurowac gniazda mozna przy pomocy dobrze znanych
,,plikowych'' funkcji ioctl()
oraz fcntl()
:
Opis ich implementacji znajduje sie w rozdziale 9.1.9
int ioctl(int fd, unsigned long request, char *arg);
Wazniejsze operacje dotyczace gniazd (wartosc argumentu request
):
SIOCSPGRP, FIOSETOWN, SIOCGPGRP, FIOGETOWN
- patrz tutaj
SIOCATMARK
- przekazuje (jako wartosc
*arg
) liczbe rozna od zera, gdy w strumieniu danych wejsciowych znajduja
sie dane wysokopriorytetowe.
W tym miejscu warto zaznaczyc, iz funkcja ioctl()
pozwala
rowniez na ustalenie wielu parametrow dotyczacych konkretnych interfejsow
sieciowych. Ich omawianie nie jest jednakze tematem niniejszego opracowania.
int fcntl(int fd, int cmd, int arg);
FNDELAY
- ustanawia operacje wejscia/wyjscia na
gniazdku nieblokujacymi - wowczas funkcje ktore zazwyczaj dzialaja
blokujaco, beda wykonywac natychmiastowy powrot i ustawiac
wartosc errno
na EWOULDBLOCK
(wyjatek:
connect()
- EINPROGRESS
).
F_SETOWN, F_GETOWN, FASYNC
- patrz tutaj
include/linux/net.h
(definicja struktury sock
)
net/core/sock.c
( implementacja
funkcji sock_set[get]sockopt() )