Smeet 0 Опубліковано: 2008-04-22 13:00:07 Share Опубліковано: 2008-04-22 13:00:07 Только что сделал на другой машине с fbsd 6.1 результат тот же. Ниже в цифрах: файл inetaccess.2.60.8.rar (374 909 байт) ipfw -a l 750 00750 267 396090 divert 15701 ip from not table(16) to table(29) out в старгейзере: -> 20.06.14 - 20.09.15 194.0.200.10 0 5876860242 0 0.000000 файл ad1821.zip 928324 байт ipfw -a l 750 00750 683 987061 divert 15701 ip from not table(16) to table(29) out -> 20.53.04 - 20.55.59 195.128.95.131 0 6350022774 0 0.000000 файл sgconfig.1.89.9.win.exe 1083939 байт ipfw -a l 750 00750 824 1228134 divert 15701 ip from not table(16) to table(29) out -> 20.30.43 - 20.34.45 194.0.200.10 0 21158627065 0 0.000000 Похоже, мусор пишется... Ссылка на сообщение Поделиться на других сайтах
Alferov 0 Опубліковано: 2008-04-22 18:30:44 Share Опубліковано: 2008-04-22 18:30:44 Вот это я и имел в виду, когда писал про изменения в RAW_PACKET::GetLen() Никто не поверил. Проявляется баг только на FreeBSD при применении модуля divert. http://local.com.ua/forum/index.php?showto...indpost&p=75275 Ссылка на сообщение Поделиться на других сайтах
Andrey Zentavr 0 Опубліковано: 2008-04-22 22:16:33 Share Опубліковано: 2008-04-22 22:16:33 *** glibc detected *** /usr/sbin/sgconf: free(): invalid next size (fast): 0x0804f0d0 *** ======= Backtrace: ========= /lib/libc.so.6[0x4cc11f41] /lib/libc.so.6(cfree+0x90)[0x4cc15580] /usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0xb7f3d0a1] /usr/lib/libstdc++.so.6(_ZdaPv+0x1d)[0xb7f3d0fd] /usr/sbin/sgconf(_Z13CreateRequestP7REQUESTPc+0x8dc)[0x804ad2c] /usr/sbin/sgconf(_Z7ProcessP7REQUEST+0x83)[0x804b1f3] /usr/sbin/sgconf(main+0x710)[0x804b9a0] /lib/libc.so.6(__libc_start_main+0xe0)[0x4cbbff70] /usr/sbin/sgconf(__gxx_personality_v0+0x95)[0x8049aa1] ======= Memory map: ======== 08048000-0804e000 r-xp 00000000 03:01 9784543 /usr/sbin/sgconf.20080423 0804e000-0804f000 rw-p 00005000 03:01 9784543 /usr/sbin/sgconf.20080423 0804f000-08070000 rw-p 0804f000 00:00 0 [heap] 4cb8b000-4cba6000 r-xp 00000000 03:01 1720362 /lib/ld-2.6.so 4cba6000-4cba7000 r--p 0001a000 03:01 1720362 /lib/ld-2.6.so 4cba7000-4cba8000 rw-p 0001b000 03:01 1720362 /lib/ld-2.6.so 4cbaa000-4ccf8000 r-xp 00000000 03:01 1720363 /lib/libc-2.6.so 4ccf8000-4ccfa000 r--p 0014e000 03:01 1720363 /lib/libc-2.6.so 4ccfa000-4ccfb000 rw-p 00150000 03:01 1720363 /lib/libc-2.6.so 4ccfb000-4ccfe000 rw-p 4ccfb000 00:00 0 4cd00000-4cd03000 r-xp 00000000 03:01 1720365 /lib/libdl-2.6.so 4cd03000-4cd04000 r--p 00002000 03:01 1720365 /lib/libdl-2.6.so 4cd04000-4cd05000 rw-p 00003000 03:01 1720365 /lib/libdl-2.6.so 4cd07000-4cd2e000 r-xp 00000000 03:01 1720368 /lib/libm-2.6.so 4cd2e000-4cd2f000 r--p 00026000 03:01 1720368 /lib/libm-2.6.so 4cd2f000-4cd30000 rw-p 00027000 03:01 1720368 /lib/libm-2.6.so 4cd44000-4cd58000 r-xp 00000000 03:01 1720364 /lib/libpthread-2.6.so 4cd58000-4cd59000 r--p 00013000 03:01 1720364 /lib/libpthread-2.6.so 4cd59000-4cd5a000 rw-p 00014000 03:01 1720364 /lib/libpthread-2.6.so 4cd5a000-4cd5c000 rw-p 4cd5a000 00:00 0 4ce65000-4ce70000 r-xp 00000000 03:01 1720371 /lib/libgcc_s-4.1.2-20070503.so.1 4ce70000-4ce71000 rw-p 0000a000 03:01 1720371 /lib/libgcc_s-4.1.2-20070503.so.1 4cf85000-4cfa1000 r-xp 00000000 03:01 9783840 /usr/lib/libexpat.so.0.5.0 4cfa1000-4cfa3000 rw-p 0001c000 03:01 9783840 /usr/lib/libexpat.so.0.5.0 b7d00000-b7d21000 rw-p b7d00000 00:00 0 b7d21000-b7e00000 ---p b7d21000 00:00 0 b7e85000-b7e87000 rw-p b7e85000 00:00 0 b7e87000-b7e8b000 r-xp 00000000 03:01 5259636 /usr/lib/stg.20080423/libstg_crypto.so b7e8b000-b7e8c000 rw-p 00003000 03:01 5259636 /usr/lib/stg.20080423/libstg_crypto.so b7e8c000-b7f69000 r-xp 00000000 03:01 9783827 /usr/lib/libstdc++.so.6.0.8 b7f69000-b7f6c000 r--p 000dd000 03:01 9783827 /usr/lib/libstdc++.so.6.0.8 b7f6c000-b7f6e000 rw-p 000e0000 03:01 9783827 /usr/lib/libstdc++.so.6.0.8 b7f6e000-b7f75000 rw-p b7f6e000 00:00 0 b7f87000-b7f91000 r-xp 00000000 03:01 9798222 /usr/lib/stg.20080423/libsrvconf.so b7f91000-b7f92000 rw-p 00009000 03:01 9798222 /usr/lib/stg.20080423/libsrvconf.so b7f92000-b7f95000 r-xp 00000000 03:01 5259635 /usr/lib/stg.20080423/libstg_common.so b7f95000-b7f96000 rw-p 00003000 03:01 5259635 /usr/lib/stg.20080423/libstg_common.so b7f96000-b7f9c000 r-xp 00000000 03:01 5259631 /usr/lib/stg.20080423/libconffiles.so b7f9c000-b7f9d000 rw-p 00005000 03:01 5259631 /usr/lib/stg.20080423/libconffiles.so b7f9d000-b7f9e000 rw-p b7f9d000 00:00 0 b7f9e000-b7f9f000 r-xp b7f9e000 00:00 0 [vdso] bfb43000-bfb59000 rw-p bfb43000 00:00 0 [stack] Версия биллинга - stg-2.404.9.7 качанная http://stg.dp.ua/download/server/2.404.9.7...404.9.7.src.tgz ОС - # cat /etc/redhat-release CentOS release 4.1 (Final) # gcc -v Using built-in specs. Target: i386-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-cpu=generic --host=i386-redhat-linux Thread model: posix gcc version 4.1.2 20070502 (Red Hat 4.1.2-12) Что может быть? Ссылка на сообщение Поделиться на других сайтах
Smeet 0 Опубліковано: 2008-04-23 01:16:17 Share Опубліковано: 2008-04-23 01:16:17 Вот это я и имел в виду, когда писал про изменения в RAW_PACKET::GetLen()Никто не поверил. Проявляется баг только на FreeBSD при применении модуля divert. http://local.com.ua/forum/index.php?showto...indpost&p=75275 Рецепт есть? P.S. что-то я не нашел в исходниках RAW_PACKET::GetLen() в каком файле? может с января уже поправили... Ссылка на сообщение Поделиться на других сайтах
Alferov 0 Опубліковано: 2008-04-23 05:44:30 Share Опубліковано: 2008-04-23 05:44:30 Там, по ссылке, есть дальше описание, откуда это, и с чем сравнивалось. Я у себя поправил эту функцию, заменив последние изменения, и у меня считает правильно. Ссылка на сообщение Поделиться на других сайтах
madf 279 Опубліковано: 2008-04-23 11:12:09 Share Опубліковано: 2008-04-23 11:12:09 Вот это я и имел в виду, когда писал про изменения в RAW_PACKET::GetLen()Никто не поверил. Проявляется баг только на FreeBSD при применении модуля divert. http://local.com.ua/forum/index.php?showto...indpost&p=75275 При чем тут "верю/не верю". Если есть объективные причины, по которой изменение типа возвращаемого функцией значения с uint16_t на uint32_t приводит к неправильному подсчету трафика - это проблема и ее нужно решать. Если кто-то без объяснений говорит что есть баг который исправляется некими шаманскими действиями - я это прийму во внимание, но отложу рассмотрение на неопределенный срок. Пока не появится логическое объяснение бага и метода его устранения. Ссылка на сообщение Поделиться на других сайтах
madf 279 Опубліковано: 2008-04-23 11:13:45 Share Опубліковано: 2008-04-23 11:13:45 Версия биллинга - stg-2.404.9.7 качанная http://stg.dp.ua/download/server/2.404.9.7...404.9.7.src.tgzОС - # cat /etc/redhat-release CentOS release 4.1 (Final) # gcc -v Using built-in specs. Target: i386-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-cpu=generic --host=i386-redhat-linux Thread model: posix gcc version 4.1.2 20070502 (Red Hat 4.1.2-12) Что может быть? Спасибо за бектрейс и информацию, но еще неплохо было-бы описать, при каких действиях это произошло. Ссылка на сообщение Поделиться на других сайтах
Smeet 0 Опубліковано: 2008-04-23 13:46:36 Share Опубліковано: 2008-04-23 13:46:36 Я у себя поправил эту функцию, заменив последние изменения, и у меня считает правильно. А у тебя новогодний релиз или уже исправленный за 6.01.08 ? Поменял я на inline uint16_t RAW_PACKET::GetLen() const в raw_ip_packet.h Теперь вместо КИЛОбайт считает МЕГАбайты, НО теперь четкая зависимость в 35раз больше реально-скаченного. Например: файл 222836 байт показывает в 7738050 байт файл 519309 байт показывает в 18316650 байт файл 1083939 байт показывает в 38053575 байт счетчики ipfw безупречны. Где-то еще собака зарыта... Ссылка на сообщение Поделиться на других сайтах
Alferov 0 Опубліковано: 2008-04-23 16:33:45 Share Опубліковано: 2008-04-23 16:33:45 Новую версию сравнивал с stg-2.4-2007.01.20-13.47.20 Результат: diff -uarN stg-2.4-2007.01.20-13.47.20/include/raw_ip_packet.h stg-2.404.9.7/include/raw_ip_packet.h --- stg-2.4-2007.01.20-13.47.20/include/raw_ip_packet.h Mon Dec 18 00:00:00 2006 +++ stg-2.404.9.7/include/raw_ip_packet.h Thu Oct 4 20:59:14 2007 @@ -28,7 +28,7 @@ uint16_t GetIPVersion() const; uint8_t GetHeaderLen() const; uint8_t GetProto() const; -uint16_t GetLen() const; +uint32_t GetLen() const; uint32_t GetSrcIP() const; uint32_t GetDstIP() const; uint16_t GetSrcPort() const; @@ -54,8 +54,10 @@ return pckt[9]; } //----------------------------------------------------------------------------- -inline uint16_t RAW_PACKET::GetLen() const +inline uint32_t RAW_PACKET::GetLen() const { +if (dataLen != -1) + return dataLen; return htons(*(uint16_t*)(pckt + 2)); } //----------------------------------------------------------------------------- Ссылка на сообщение Поделиться на других сайтах
Alferov 0 Опубліковано: 2008-04-23 16:38:50 Share Опубліковано: 2008-04-23 16:38:50 При чем тут "верю/не верю". Если есть объективные причины, по которой изменение типа возвращаемого функцией значения с uint16_t на uint32_t приводит к неправильному подсчету трафика - это проблема и ее нужно решать. Если кто-то без объяснений говорит что есть баг который исправляется некими шаманскими действиями - я это прийму во внимание, но отложу рассмотрение на неопределенный срок. Пока не появится логическое объяснение бага и метода его устранения. Если почитать ответы на тот мой вопрос, то будет понятно, что произвести "шаманские действия" было рекомендовано не мной, а мне. Поэтому я просто не стал настаивать... и решил проблему сам. Как решил - имхо не важно, важно, что она решена и больше не проявляется. А какие объяснения нужны к багу? Я что то не понимаю, честное слово. Логического или какого то еще объяснения этому багу у меня нет. Кроме того, что баг реально устраняется заменой кода на код из предыдущей стабильной(!!!) версии СТГ. Хочу заметить, что я ничего не требую. Просто пытаюсь обратить внимание разработчиков на баг. Спасибо за внимание. Ссылка на сообщение Поделиться на других сайтах
Andrey Zentavr 0 Опубліковано: 2008-04-23 21:05:29 Share Опубліковано: 2008-04-23 21:05:29 (відредаговано) Версия биллинга - stg-2.404.9.7 качанная http://stg.dp.ua/download/server/2.404.9.7...404.9.7.src.tgzОС - # cat /etc/redhat-release CentOS release 4.1 (Final) # gcc -v Using built-in specs. Target: i386-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-cpu=generic --host=i386-redhat-linux Thread model: posix gcc version 4.1.2 20070502 (Red Hat 4.1.2-12) Что может быть? Спасибо за бектрейс и информацию, но еще неплохо было-бы описать, при каких действиях это произошло. Да есть у меня скрипт, который автоматом бонусы юзерам добавляет. Выполняет нечто вроде /usr/sbin/sgconf -s 127.0.0.1 -p 4444 -a zentavr -w pass13 -u yolka -c "10:Бонус за March 2008" ЗЫ: Заметил, что такая хня случается, когда длинна коммента больше 13 символов Відредаговано 2008-04-23 21:23:33 Andrey Zentavr Ссылка на сообщение Поделиться на других сайтах
Smeet 0 Опубліковано: 2008-04-24 07:13:54 Share Опубліковано: 2008-04-24 07:13:54 To: Alferov Cпасибо тебе огромное! Закоментировал еще строчки: if (dataLen != -1) return dataLen; И все считает как часы! Если бы ты сразу добавил изменения в свой патч, цены бы тебе не было. )) Попутный вопрос: как у тебя сделано в файле divert_cap.cpp строка 308 по-умолчанию?: "0, (struct sockaddr*) &divertaddr, &divertaddrSize)) > 50)" Если да, то вынес ли ты за скобку: sendto(cddiv.sock, buf, bytes, 0, (struct sockaddr*)&divertaddr, divertaddrSize); У меня по-умолчанию не работает. Нужно ставить или >10 или за скобку выносить. Ссылка на сообщение Поделиться на других сайтах
Alferov 0 Опубліковано: 2008-04-24 16:28:00 Share Опубліковано: 2008-04-24 16:28:00 Я у себя закомментировал возврат (sendto(...)) и сделал не divert в фаере, а tee Т.е. принцип такой, работает биллинг или нет - инет у клиента должен быть всегда. Ссылка на сообщение Поделиться на других сайтах
Smeet 0 Опубліковано: 2008-04-25 01:18:43 Share Опубліковано: 2008-04-25 01:18:43 to Madf: у меня по-умолчанию "0, (struct sockaddr*) &divertaddr, &divertaddrSize)) > 50)" при выносе за скобку (sendto(...)) считает на 30% больше, а при "0, (struct sockaddr*) &divertaddr, &divertaddrSize)) > 10)" все точно без выноса (sendto(...) Еще одна неприятная особенность. Строка в конфиге ModulesPath = /usr/lib/stg2.404 не отрабатывается или отрабатывается частично, потому как если удалить /usr/lib/stg то выдает: /libexec/ld-elf.so.1: Shared object "libstg_logger.so" not found, required by "stargazer" уже новую версию на этой же машине не потестишь... Ссылка на сообщение Поделиться на других сайтах
madf 279 Опубліковано: 2008-04-25 06:03:05 Share Опубліковано: 2008-04-25 06:03:05 to Madf: у меня по-умолчанию "0, (struct sockaddr*) &divertaddr, &divertaddrSize)) > 50)" при выносе за скобку (sendto(...)) считает на 30% больше, а при "0, (struct sockaddr*) &divertaddr, &divertaddrSize)) > 10)" все точно без выноса (sendto(...) Еще одна неприятная особенность. Строка в конфиге ModulesPath = /usr/lib/stg2.404 не отрабатывается или отрабатывается частично, потому как если удалить /usr/lib/stg то выдает: /libexec/ld-elf.so.1: Shared object "libstg_logger.so" not found, required by "stargazer" уже новую версию на этой же машине не потестишь... По первому - ничего не могу сказать. Фря - странная и загадочная система. Как при более жестком условии в счетчик может попасть больше пакетов чем при более мягком - ума не приложу. По второму: кроме модулей есть еще динамические библиотеки. Без них система рабоать не может. По умолчанию используются те, которые лежат в /usr/lib/stg. Чтобы использовать библиотеки из другого места нужно записать в переменную окружения LD_LIBRARY_PATH путь к библиотекам. Так, например, для запуска старгейзера из каталога сборки в конфиге путь к модулям прописывается ./modules, а сам он запускается командой: LD_LIBRARY_PATH=../../lib ./stargazer Ссылка на сообщение Поделиться на других сайтах
vovksextra 0 Опубліковано: 2008-04-25 18:33:41 Share Опубліковано: 2008-04-25 18:33:41 Фря - странная и загадочная система. Пока не начала писать под ФРЮ я тоже так думал.Просто фря более щепетильна ко всякому роду багов, которых ее наделали программисты. А теперь по делу. Недавно недельки (три назад) мы начали писать биллинг на (FPC). Написали модуль перехвата пакетов через BPF и через IPFW. Для ускорения работы взяли за основу исходники старгейзера. Когда настал тот миг когда мы смогли посчитать траффик выяснилось: 1. через BPF к нам не попадает очень большая часть пакетов. А если выставить скорость 100 Мб/с. то пакетов приходит всего 5%. 2. Через Диверт - вообще ничего не принимал. Далее начался процесс поиска инфы со всех источников. 1. Диверт побороли сразу. Что сделали 1. Приняли пакет 2. Если длина принятых данных больше чем размер IP хидера+ICMP хидера - пустили на прасер 3. Отдали его в таком состоянии как и приняли (Sendto). В Старгейзере немного другой алгоритм. Он просто ест ICMP пакеты и не только.... 2. Что касается BPF Полазив по докам выяснили что ФРЯ может выделить командой BIOCSBLEN буфер длиной аж 525Кб (Старгейзер выделяет всего лишь 128 байт, разработчик пытался получать только заголовки - вот и попался) И пока он обрабатывает очередной пакет в ядре идет просто переполнение буфера приема и ядро съедает все пакеты которые стоят в очереди. Полечилось очень просто выставили буфер в 1Мб вызвали Ioctl + BIOCSBLEN , прочитали тот размер буфера который нам был выделен и все. Правда пришлось переделать сам алгоритм приема. вот переделанный алгоритм function DoRun(p: pointer): pointer; cdecl; var ubpf: TPacketSniffer; begin ubpf := TPacketSniffer(p); ubpf.isRunning := True; log('Entering BPF thread'); while not ubpf.isStoped do begin ubpf.RecvPacket; end; ubpf.isRunning := False; log('Exiting BPF thread'); DoRun := nil; pthread_exit(nil); end; procedure TPacketSniffer.RecvPacket; var R: PRecInterface; BPF_HDR: PBPF_HDR; pbuff: PChar; packet: TPacket; i: integer; res: integer; begin for i := 0 to FListInterfaces.Count - 1 do begin R := PRecInterface(FListInterfaces.Items[i]); if R^.isOpen then begin fppoll(@R^.FPoll, 1, 1); if (R^.FPoll.revents and POLLIN) = 1 then begin R^.FPoll.revents := 0; res := fpRead(R^.fd, buff, BUFF_LEN); if res > 0 then begin pbuff := buff; while pbuff < buff + res do begin BPF_HDR := PBPF_HDR(pbuff); if GetIPPacket(pbuff + BPF_HDR^.bh_hdrlen, packet) then begin Inc(R^.Count); packet.intf := 1 shl i; packet.date := BPF_HDR^.bh_tstamp; if Assigned(FOnPacket) then FOnPacket(packet); end; pbuff := pbuff + BPF_WORDALIGN(BPF_HDR^.bh_caplen + BPF_HDR^.bh_hdrlen); end; end; end; end; end; end; Уже при буфере в 256 к на скорости 100Мбит - не теряется ни один пакет ))) На эксперементальном сервере стоит проц. дурон 1.6 и ОЗУ 512.И даже poll не помеха. Руководствовался вот этим: http://osdir.com/ml/network.tcpdump.devel/...0/msg00043.html Although we didn't implement the get/set bufsize functions for other platforms, I did some research and found the following: DEF = default buffer size DEFMAX = max buffer size without kernel tuning MAX = inherent limit for kernel buffering * bpf BIOCSBLEN FreeBSD DEF = 4-32K depending DEFMAX = 512K-1M MAX = 16M(?) AIX ??? И вот этим http://canmore.annwfn.net/freebsd/bpf.html Сам алгортим разбора пакетов брал здесь: http://packetstormsecurity.org/sniffers/gdd13.c Так что если разрабочики подкоректируют алгоритм подсчета трафика через BPF - то "трудоемкий" диверт просто будет не нужен. А что касается потери данных на ФРЕ при попытке закрыть приложение - это отдельная тема. Есть две проблемы: 1. первая - перехват сигналов. (Это отдельная тема) 2. что мне удалось словить - это закрытие потоков , а именно таймаута в 5 секунд - обычно мало что-бы выйти из цикла и произвести все процедуры записи. Ежели 5 секунд истекло а поток все еще работает вызывается тривиальный pthread_kill(ххххх, SIGINT). 3. Да и вообще организована не правильная работа с потоками. Линкс кушает а вот ФРЯ ....... Например вырезка из кода int USERS::Start() { if (ReadUsers()) { WriteServLog("USERS: Error: Cannot read users!"); return -1; } nonstop = true; if (pthread_create(&thread, NULL, Run, this)) { WriteServLog("USERS: Error: Cannot start thread!"); return -1; } return 0; } Обратим внимание на pthread_create(&thread, NULL, Run, this) в качестве атрибутов - передано NULL Значит у нас будет создана подключаемая нить (THREAD_CREATE_JOINABLE) Если была создана подключаемая нить, для нее необходимо вызвать функцию pthread_join. В противном случае в системе может оказаться недостаточно памяти для создания новой нити, так как каждая нить занимает относительно большой объем. Более подробная информация о функции pthread_join . Источник: http://publib.boulder.ibm.com/infocenter/s...n_variables.htm Нужно грамотно делать так пример на fpc pthread_attr_init(@attr); pthread_attr_setdetachstate(@attr, PTHREAD_CREATE_DETACHED); res := pthread_create(@ThreadBPF, @attr, @DoRun, Self); pthread_attr_destroy(@attr); и т.д. но тогда перестают работать такие вещи как sigaction(SIGTERM, &newsa, &oldsa); (на фре это точно, не знаю как на линкусе) Тему поднимал здесь: http://forum.vingrad.ru/forum/topic-206058.html ответов не дали. пришлось переделывать MainLoop Вырезка из кода. procedure MainLoop; var sigmask: sigset_t; threadID: pthread_t; begin fpSigfillset(sigmask); fpSigdelset(sigmask, SIGKILL); fpSigdelset(sigmask, SIGSTOP); fpSigdelset(sigmask, SIGCONT); pthread_sigmask(SIG_BLOCK, @sigmask, nil); pthread_create(@threadID, nil, @DoRun, nil); log('Signal main thread started for: SIGHUP, SIGTERM, or SIGINT (shell ctrl-c)'); pthread_join(threadID, nil); end; Вот здесь очень удачное решение !!!!!! http://damao.net/vhosts/node.to/sigtest.tgz вообщем ловить баги при такой реализации - дело очень плохое. Вот и дергнуло нас написать свой биллинг с авторизатором. Много вопросов возникло с самой авторизацией, а именно "всякие там" фазы. Уж больно все сложно - Из-за этих фаз и началось все. Поставили новый релиз - перешли на Фиреберд и тут на тебе - клиенты начали "залипать". Переписали свой алгоритм - до боли простой Клиент раз в 5 секунд передает пакет Ping - сервер отвечает Pong (вместе с инфой))). И на сервере крутится поток который ищет всех абонентов от которых он некоторый период не получал Ping и отключает от сессии. Все довольно просто - зачем нужно все так усложнять. Ссылка на сообщение Поделиться на других сайтах
Stiff 0 Опубліковано: 2008-04-27 08:41:10 Share Опубліковано: 2008-04-27 08:41:10 Помогите разобраться с проблемой Установлена новогодняя версия стг (2.404.9.7) на сервер с линуксом ubuntu server 7.10. Подключаюсь виндовым конфигуратором версии 1.89.9. Подключение проходит в нормальном режиме, пользователи создаются нормально. Но загвоздка возникает, когда пытаюсь сменить тип учитываемого трафика с upload на что-то другое. После нажатия кнопки "сохранить" после закрытия окошка "тариф успешно изменён" это значение везде сбрасывается на "upload" обратно. Пытался использовать модули сохранения mysql и files - результат одинаковый. вот что выводит стг во время смены тарифа: parser.cpp > 16:29:32 > PARSER_SEND_MESSAGE::ParseStart el = SetTariff configproto.cpp > 16:29:32 > Start parser_tariff.cpp > 16:29:32 > PARSER_GET_TARIFFS::ParseStart configproto.cpp > 16:29:32 > Start parser_tariff.cpp > 16:29:32 > PARSER_ADD_TARIFF::ParseStart configproto.cpp > 16:29:32 > Start parser_tariff.cpp > 16:29:32 > PARSER_DEL_TARIFF::ParseStart configproto.cpp > 16:29:32 > Start parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = SetTariff depth = 1 configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = Time0 depth = 2 configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = TraffType0 depth = 2 configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = Time1 depth = 2 configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = TraffType1 depth = 2 configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = Time2 depth = 2 configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = TraffType2 depth = 2 configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = Time3 depth = 2 configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = TraffType3 depth = 2 configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = Time4 depth = 2 configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = TraffType4 depth = 2 configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = Time5 depth = 2 configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = TraffType5 depth = 2 configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = Time6 depth = 2 configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = TraffType6 depth = 2 configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = Time7 depth = 2 configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = TraffType7 depth = 2 configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = Time8 depth = 2 configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = TraffType8 depth = 2 configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = Time9 depth = 2 configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = TraffType9 depth = 2 configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = PriceDayA depth = 2 parser_tariff.cpp > 16:29:32 > ParseSlashedDoubleParams - OK!!! configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = PriceDayB depth = 2 parser_tariff.cpp > 16:29:32 > ParseSlashedDoubleParams - OK!!! configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = PriceNightA depth = 2 parser_tariff.cpp > 16:29:32 > ParseSlashedDoubleParams - OK!!! configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = PriceNightB depth = 2 parser_tariff.cpp > 16:29:32 > ParseSlashedDoubleParams - OK!!! configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = Threshold depth = 2 parser_tariff.cpp > 16:29:32 > ParseSlashedIntParams - OK!!! configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = SinglePrice depth = 2 parser_tariff.cpp > 16:29:32 > ParseSlashedIntParams - OK!!! configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = NoDiscount depth = 2 parser_tariff.cpp > 16:29:32 > ParseSlashedIntParams - OK!!! configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = Fee depth = 2 configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = Free depth = 2 configproto.cpp > 16:29:32 > ParseXMLStart parser_tariff.cpp > 16:29:32 > PARSER_CHG_TARIFF::ParseStart el = PassiveCost depth = 2 configproto.cpp > 16:29:32 > currParser == NULL Сталкивался ли кто-нибудь с таким? Подскажите, в какую сторону копать? Ссылка на сообщение Поделиться на других сайтах
madf 279 Опубліковано: 2008-04-27 09:11:38 Share Опубліковано: 2008-04-27 09:11:38 2vovksextra: За развернутый пост спасибо, анализирую. По поводу буфера ты не совсем прав, т.к. если скорость обработки ниже скорости приема любого размера буфер когда-нибуть заполнится. По поводу joinable-threads тоже не совсем так. Единственная "фишка", которая происходит если не сделать join - "утечка" памяти. Но, т.к. это происходит при останове программы - оно никак не влияет на систему. После останова вся память распределенная программе будет освобождена ОС. Потеря данных при kill, если поток не остановился за 5 сек? Ну что ж, можно таймаут сделать конфигурабельным. 2Stiff: Сегодня проверю. Ссылка на сообщение Поделиться на других сайтах
vovksextra 0 Опубліковано: 2008-04-27 10:23:17 Share Опубліковано: 2008-04-27 10:23:17 2vovksextra:За развернутый пост спасибо, анализирую. По поводу буфера ты не совсем прав, т.к. если скорость обработки ниже скорости приема любого размера буфер когда-нибуть заполнится. Но ведь будет лучше если ты прочитаешь по "максимуму" и "быстренько" распарсишь. А пока будешь парсить - буфер не успеет переполниться. И что касается буфера - увелить его и увидишь положительные отзывы )) а иначе зачем нужен этот код при 128 байтах )) Он теряет весь свой смысл. if(bd->r > bd->sum) { memcpy(buffer, (char*)(bd->p) + bd->bh->bh_hdrlen, blen); //strncpy(iface, settings->iface[n], 9); //*iface = settings->iface[n]; bd->sum += BPF_WORDALIGN(bd->bh->bh_hdrlen + bd->bh->bh_caplen); bd->p = bd->p + BPF_WORDALIGN(bd->bh->bh_hdrlen + bd->bh->bh_caplen); bd->bh = (struct bpf_hdr*)bd->p; } Если у тебя стоит фря могу скинуть бинарник + авторизатор - поссмотришь как живенько все считает на 100Мбит - загрузка проца 0.1%. Если поставишь fpc - могу дать наработки, которые уже есть. И еще уж очень сильно накрутили с выполнением скриптов. Я взял код выполнения скриптов у Netams - немного переделал (Заменил execl на popen и pclose ) получилось просто и сердито. function ExecuteScript(FNameScript: string; FParams: string): cint; var pid: cint; ign, intact, quitact: SigactionRec; newsigblock, oldsigblock: tsigset; f: textfile; s: string; begin result := 0; if fpaccess(FNameScript, X_OK) <> 0 then begin result := -1; exit; end; ign.sa_handler := SigActionHandler(SIG_IGN); fpsigemptyset(ign.sa_mask); ign.sa_flags := 0; fpsigaction(SIGINT, @ign, @intact); fpsigaction(SIGQUIT, @ign, @quitact); fpsigemptyset(newsigblock); fpsigaddset(newsigblock, SIGCHLD); fpsigprocmask(SIG_BLOCK, newsigblock, oldsigblock); pid := fpFork; case pid of -1: result := -1; 0: begin fpsigaction(SIGINT, @intact, nil); fpsigaction(SIGQUIT, @quitact, nil); fpsigprocmask(SIG_SETMASK, @oldsigblock, nil); s := FNameScript + ' ' + FParams; popen(f, s, 'r'); if fpgeterrno = 0 then pclose(f); fpExit(127); end; end; fpsigaction(SIGINT, @intact, nil); fpsigaction(SIGQUIT, @quitact, nil); fpsigprocmask(SIG_SETMASK, @oldsigblock, nil); end; Ссылка на сообщение Поделиться на других сайтах
madf 279 Опубліковано: 2008-04-27 10:46:31 Share Опубліковано: 2008-04-27 10:46:31 По поводу выполнения скриптов. Не понимаю, какой смысл открывать пайп через popen, если нам не нужен stdout скрипта. Почему такая сложная схема реализована в stg? Потому что совместная работа fork и POSIX Threads вызывала немыслимые глюки на старых ядрах. Ссылка на сообщение Поделиться на других сайтах
vovksextra 0 Опубліковано: 2008-04-27 11:22:01 Share Опубліковано: 2008-04-27 11:22:01 По поводу выполнения скриптов. Не понимаю, какой смысл открывать пайп через popen, если нам не нужен stdout скрипта.Почему такая сложная схема реализована в stg? Потому что совместная работа fork и POSIX Threads вызывала немыслимые глюки на старых ядрах. Просто не хотел готовить список параметров в виде ppchar для вызова exec-ов. В паскале нужно брать бубен в руки для такого рода операций. )) А что касается глюков fork и POSIX Threads - может все дело не в "старых ядрах", а в не умелом использовании нитей. ;-) Я когда создал нить (делал точно так как в старгейезере) откопилировал под фрю она вообще не "заводилась" без pthread_join, а когда ее подключил, то обработчик сигналов не реагировал ни в какую на нее. Это было до тех пор пока я не сделал отключаемую нить и не переделал main loop (это единственная нить подключаемая во всем приложении) в предыдущем посте я выложил пример. Я вообще перестал после всего того что я перепробывал - понимать как вообще работает код старгейзера.......Но это так мысли в слух. А насчет буфера bpf увеличь его и проблема потери пакетов будет решена ))) Также очень долго не мог понять зачем в модуле Inetaccess нужна интересная процедура DummySend. Когда в своем коде наткнулся на этот эффект начал понимать ))) Сначала ее повторил, но как-то все не красиво получилось. Перешел на poll и не нужно было ждать 2,5 секунды что-б она вызвалась (разработчик поймет о чем идет речь) А также я увидел очень много вещей мне не понятных и не поддающихся логике . Вообщем пора начинать писать stargazer 3.0 (желательно с нуля) иначе тупик. Не сегодня так завтра. Вообщем сама идея такого рода биллинга с таким функционалом 5+++ и аналогов нет - но очень хромает реализация. Думаю что за 6 лет можно было и порядок навести. Думаю что критика будет воспринята адекватно. PS Когда перешли на новый релиз + фиреберд - думали что проблема с пропаданием данных решится - но не так-то было. 1. Когда завели админа и перегрузили сервер - то в поле пароль стали крякозяблы. 2. Залипают пользователи (это проблема уже поднималась - грешили на "фазы") 3. Самое интересное - по непонятным причинам - примерно в 20-00 каждый день - старгейзер (новый) переставал считать трафик (юзера ходили на шару). Как следствие каждый день в 19-45 перегружали сервер, заводили админов и т.д. В итоге перешли на старый релиз (временно - пока свой не заведем) проблема пустых файлов решается постоянным "таром" проблема Broken pipe - решилась закомментированием записи в лог Вот такие вот дела .... Ссылка на сообщение Поделиться на других сайтах
madf 279 Опубліковано: 2008-04-27 12:53:25 Share Опубліковано: 2008-04-27 12:53:25 Какие-то ты страшные страсти рассказываеш про joinable threads. Написал небольшое тестовое приложение: создает дэфолтную нить, ждет 5 сек и завершается. Нить тупо считает сумму чисел до 1000000 с периодическим выводом и завершается (раньше 5 сек). Запустил у себя на Gentoo Linux - отработала нормально. Пустил под valgrind: ==6476== malloc/free: in use at exit: 68 bytes in 1 blocks. ==6476== malloc/free: 1 allocs, 0 frees, 68 bytes allocated. ==6476== LEAK SUMMARY: ==6476== definitely lost: 0 bytes in 0 blocks. ==6476== possibly lost: 68 bytes in 1 blocks. ==6476== still reachable: 0 bytes in 0 blocks. ==6476== suppressed: 0 bytes in 0 blocks. - все как и описано в документации (pthread_join не делал). Собрал и запустил на FreeBSD 4.6-RELEASE-p2 с библиотекой libc_r. Отработало так-же как и под Gentoo Linux. Сейчас еще на 5-й попробую. На какой версии фри и с какой либой у тебя глюки вылезали? Ссылка на сообщение Поделиться на других сайтах
vovksextra 0 Опубліковано: 2008-04-27 13:05:14 Share Опубліковано: 2008-04-27 13:05:14 Какие-то ты страшные страсти рассказываеш про joinable threads. Написал небольшое тестовое приложение: создает дэфолтную нить, ждет 5 сек и завершается. Нить тупо считает сумму чисел до 1000000 с периодическим выводом и завершается (раньше 5 сек).Запустил у себя на Gentoo Linux - отработала нормально. Пустил под valgrind: ==6476== malloc/free: in use at exit: 68 bytes in 1 blocks. ==6476== malloc/free: 1 allocs, 0 frees, 68 bytes allocated. ==6476== LEAK SUMMARY: ==6476== definitely lost: 0 bytes in 0 blocks. ==6476== possibly lost: 68 bytes in 1 blocks. ==6476== still reachable: 0 bytes in 0 blocks. ==6476== suppressed: 0 bytes in 0 blocks. - все как и описано в документации (pthread_join не делал). Собрал и запустил на FreeBSD 4.6-RELEASE-p2 с библиотекой libc_r. Отработало так-же как и под Gentoo Linux. Сейчас еще на 5-й попробую. На какой версии фри и с какой либой у тебя глюки вылезали? Пишу под FreeBSD 6.3 , компилятор fpc 2.2.0, использую libphtread. Поставь с портов FPC - я для тебя сделаю код (похожий как у СТЖ) - откомпилишь и глянешь сам . А затем сделаю как нужно и еще раз глянешь. Иначе нет смысла вести диалог. Ссылка на сообщение Поделиться на других сайтах
madf 279 Опубліковано: 2008-04-27 13:13:04 Share Опубліковано: 2008-04-27 13:13:04 Пишу под FreeBSD 6.3 , компилятор fpc 2.2.0, использую libphtread. Поставь с портов FPC - я для тебя сделаю код (похожий как у СТЖ) - откомпилишь и глянешь сам . А затем сделаю как нужно и еще раз глянешь. Иначе нет смысла вести диалог. А, ну все понятно. fpc - FreePascal? То у тебя паскаль так с нитями дружит. PS: проверил тот-же пример на FreeBSD 5.3-RELEASE с теми-же результатами Ссылка на сообщение Поделиться на других сайтах
vovksextra 0 Опубліковано: 2008-04-27 13:48:27 Share Опубліковано: 2008-04-27 13:48:27 Пишу под FreeBSD 6.3 , компилятор fpc 2.2.0, использую libphtread. Поставь с портов FPC - я для тебя сделаю код (похожий как у СТЖ) - откомпилишь и глянешь сам . А затем сделаю как нужно и еще раз глянешь. Иначе нет смысла вести диалог. А, ну все понятно. fpc - FreePascal? То у тебя паскаль так с нитями дружит. PS: проверил тот-же пример на FreeBSD 5.3-RELEASE с теми-же результатами что значит так дружит с нитями? Вызываются все-равно ведь API функции и процедуры ))) (если ты не знаешь то могу сказать что FPC это не интерпретатор а компилятор ) Если функция или процедура не описана ее можно запросто подключить, например так function fpsigwait(__set:psigset_t; __sig:plongint):longint;cdecl;external name 'sigwait'; external - говорит что она внешняя и выше нужно описать какую либу подключить. вот и все. А древние стереотипы о качестве той или иной среде разработке тебе не мешало-бы давно стереть ))) Ибо один х..й - только вид сбоку. Мне просто не понятно где в коде СТЖ используются методы pthread_sigmask и тому подобные вещи !!!!!!!!!!!!!! Как вообще код СТЖ попадает в перехватчик сигналов ????? У меня при такой реализации код вообще не выходил из главного цикла при SIGINT например......А тупо прерывался где хотел. Ибо не понятно какя именно нить получит сигнал. Или что то я не понимаю..... А что касается того что я говорил: Для неотделенного (PTHREAD_CREATE_JOINABLE) потока очень важно, чтобы после того, как он завершится, к нему присоединился другой поток, - иначе ресурсы этого потока не будут освобождены для использования новыми потоками. Это обычно приводит к утечке памяти. Если не требуется создавать поток, который будет присоединен, нужно создавать его ОТДЕЛЬНЫМ. вообщем спорить здесь нечего - у меня все завелось и работает в отличие от СТЖ а разработчику советую поссмотреть в сторону sigwait и в сторону отключаемых потоков и еще поссмотри здесь. Думаю здесь самое правильно решение http://damao.net/vhosts/node.to/sigtest.tgz а то что завелся одиночный поток - это еще не показатель. Ссылка на сообщение Поделиться на других сайтах
Рекомендованные сообщения