UNIX: разработка сетевых приложений
11.10. Когда клиент выводит
, функцияTrying 206.62.226.35...возвращает IP-адрес. Пауза перед этим выводом означает, что распознаватель ищет имя узла. Выводgethostnameзначит, что функцияConnected to bsdi.unpbook.com.возвратила управление. Пауза между этими двумя выводами говорит о том, что функция connect пытается установить соединение.connectГлава 12
12.1. Далее приведен сокращенный листинг. Обратите внимание, что клиент FTP в системе
всегда пытается использовать командуfreebsd(независимо от версии IP), но если это не срабатывает, то он пробует командуEPRT.PORTfreebsd % <b>ftp aix-4</b>Connected to aix-4.unpbook.com.220 aix FTP server ......230 Guest login ok. access restrictions apply.ftp> <b>debug</b>Debugging on (debug=1).ftp> <b>passive</b>Passive mode: off; fallback to active mode= offftp> <b>dir</b>---> EPRT |1|192 168.42.1|50484|500 'EPRT |1|192.168.42.1|50484|' command not understood.disabling epsv4 for this connection---> PORT 192.168.42.1.197.52200 PORT command successful.---> LIST150 Opening ASCII mode data connection for /bin/ls...freebsd % <b>ftp ftp.kame.net</b>Trying 2001.200:0:4819:203:47ff:fea5:3085...Connected to orange.kame.net.220 orange.kame.net FTP server ......230 Guest login ok. access restrictions apply.ftp> <b>debug</b>Debugging on (debug=1).ftp> <b>passive</b>Passive mode: off; fallback to active mode: off.ftp> <b>dir</b>---> EPRT |2|3ffe:b80:3:9ad1::2|50480|200 EPRT command successful---> LIST150 Opening ASCII mode data connection for '/bin/ls'.Глава 13
13.1. Все сообщения об ошибках, даже ошибка загрузки, такая как неправильный аргумент командной строки, должны сохраняться в файлах журнала с помощью функции
.syslog13.2. TCP-версии серверов
,echoиdiscardзапускаются как дочерние процессы, после того как демонchargenвызовет функциюinetd, поскольку эти три сервера работают, пока клиент не прервет соединение. Два других TCP-сервера,forkиtime, не требуют использования функцииdaytime, поскольку эти службы легко реализовать (получить текущую дату, преобразовать ее, записать и закрыть соединение). Эти два сервера обрабатываются непосредственно демономfork. Все пять UDP-служб обрабатываются без использования функцииinetd, поскольку каждая из них генерирует единственную дейтаграмму в ответ на клиентскую дейтаграмму, которая запускает эту службу. Эти пять служб обрабатываются напрямую демономfork.inetd13.3. Это известная атака типа «отказ в обслуживании» [18]. Первая дейтаграмма с порта 7 заставляет сервер
отправить дейтаграмму обратно на порт 7. На эту дейтаграмму приходит эхо-ответ, и серверуchargenпосылается другая дейтаграмма. Происходит зацикливание. Одним из решений, реализованным в системе BSD/OS, является игнорирование дейтаграмм, направленных любому внутреннему серверу, если номер порта отправителя пришедшей дейтаграммы принадлежит одному из внутренних серверов. Другим решением может быть запрещение этих внутренних служб — либо с помощью демонаchargenна каждом узле, либо на маршрутизаторе, связывающем внутреннюю сеть организации с Интернетом.inetd13.4. IP-адрес и номер порта клиента могут быть получены из структуры адреса сокета, заполняемой функцией
.acceptПричина, по которой демон
не делает этого для UDP-сокета, состоит в том, что чтение дейтаграмм (inetd) осуществляется с помощью функцииrecvfromсервером, а не самим демономexec.inetdДемон
может считать дейтаграмму с флагомinetd(см. раздел 14.7), только чтобы получить IP-адрес и номер порта клиента, но оставляет саму дейтаграмму для чтения серверу.MSG_PEEKГлава 14
14.1. Если не установлен обработчик, первый вызов функции
будет возвращать значениеsignal, а вызов функцииSIG_DFLдля восстановления обработчика просто вернет его в исходное состояние.signal14.3. Приведем цикл
:forfor (;;) {if ((n = Recv(sockfd, recvline, MAXLINE, MSG_PEEK)) == 0)break; /* сервер закрыл соединение */Ioctl(sockfd, FIONREAD, &npend);printf("%d bytes from PEEK, %d bytes pending\n", n, npend);n = Read(sockfd, recvline, MAXLINE);recvline[n] = 0; /* завершающий нуль */Fputs(recvline, stdout);}14.4. Данные продолжают выводиться, поскольку выход из функции
— это то же самое, что и возврат из этой функции. Функцияmainвызывается программой запуска на языке С следующим образом:main