1. Си / Говнокод #17139

    +136

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    len += sprintf(event_xml_msg, XML_TAG_START, XML_KOKOKO_HTTP_PROTOCOL);
    
    	// Set <monitor-event>
    	len += sprintf(strend_ptr(event_xml_msg), XML_TAG_START, XML_MONITOR_EVENT_NODE_TREE);
    
    	// Set <date>
    	len += xml_string_add_tag(event_xml_msg, XML_MONITOR_EVENT_NODE_DATE, dt.date_b);
    
    	// Set <time>
    	len += xml_string_add_tag(event_xml_msg, XML_MONITOR_EVENT_NODE_TIME, dt.time_b);
    
    	// Set <product> Ex. "VersAtive"
    	len += xml_string_add_tag(event_xml_msg, XML_MONITOR_EVENT_NODE_PRODUCT, product_type);
    
    	// Set <entity code>
    	// Supposed to work for all union types
    	len += xml_int_add_tag(event_xml_msg, XML_MONITOR_EVENT_NODE_CODE, event_code);
    
    	// Set <severity>
    	//	len += xml_int_add_tag(event_xml_msg, XML_MONITOR_EVENT_NODE_SEVERITY, severity);
    	memset(severity_str, 0, sizeof(severity_str));
    	get_severity_string(severity, severity_str);
    	len += xml_string_add_tag(event_xml_msg, XML_MONITOR_EVENT_NODE_SEVERITY, severity_str);
    
    	// Set event entity name
    	len += xml_string_add_tag(event_xml_msg, XML_MONITOR_EVENT_NODE_ENTITY_TYPE, entity_name);
    
    	// Set event description
    	if((len + strlen(description)) > (payload_size - footer_size))
    	{
    		// TODO HANDLE
    		printf("Message description overflows buffer size.\n");
    		return false;
    	}
    	len += xml_cdata_string_add_tag(event_xml_msg, XML_MONITOR_EVENT_NODE_DESCRIPTION, description);
    
    	// Set params
    	add_xml_entity_params(event_xml_msg, entity_params);
    
    	// Close <monitor-event>
    	sprintf(strend_ptr(event_xml_msg), XML_TAG_END, XML_MONITOR_EVENT_NODE_TREE);
    
    	// Close <HTTPProtocol>
    	len += sprintf(strend_ptr(event_xml_msg), XML_TAG_END, XML_KOKOKO_HTTP_PROTOCOL);

    В проекте широко используется libmxml, а вот блять использовать его по назначению велосипедики не могут.

    Запостил: codemonkey, 20 Ноября 2014

    Комментарии (56) RSS

    • низкоуровневые программисты проклинают этот убогий, тормозной, неудобный формат, придуманный неосиляторами для неосиляторов!
      Ответить
      • s/низкоуровневые/компетентые/g

        p.s: Прошу админов выпилить коммент с product name из ГК.
        Ответить
        • не сказал бы - никто и не заметил бы
          админы не читают комменты
          ищи внизу "обратная связь", но шансов на успех около 1%
          Ответить
    • >XML_KOKOKO_HTTP_PROTOCOL
      Простите, что?
      Ответить
      • он устроился на работу
        Ответить
        • Причем сразу архитектором, раз протоколы проектирует.
          Ответить
      • Имена изменены в защиту сирых и убогих. Surely you cannot be serious что кто нибудь назовёт протокол "кококо".
        Ответить
    • Генери XML руками
      @
      Налетай на проблемы с экскейпингом
      ----------
      На все замечания про готовые решения
      @
      Отвечай что они медленные, а для такой простой задачи хватит и printf
      Ответить
      • > if((len + strlen(description)) > (payload_size - footer_size))
        И шанс на переполнение буфера ну никак нельзя было упустить...

        P.S. Или в footer_size уже учтена длина сериализованных entity_params и обертка в виде CDATA вокруг description?
        Ответить
        • footer_size оказался сраным дефайном на 128 байт. Смысл сего не ясен.

          Кроме того, весь payload ограничен 4 КБ.
          Ответить
          • > 128 байт
            Ну типа автор на 146% уверен, что всё, что ниже description'а (и обертка вокруг него тоже) всяко меньше, чем 128 байт...

            Т.е. переполнение буфера подтверждается: даже если все эти add_xml_* растягивают буфер (что маловероятно), sprintf'ы в 41 и 44 - нет.
            Ответить
            • Вот один такой xml_add_faggot:

              int xml_string_add_tag(char *msg, const char *tag, const char *val)
              {
              return sprintf(strend_ptr(msg), XML_TAG_START"%s"XML_TAG_END, tag, val, tag);
              }
              Ответить
              • Я это себе как-то так и представлял...
                #define XML_TAG_START "<%s>"
                #define XML_TAG_END "</%s>"
                Ответить
                • Так точно.

                  А эти макро вообще шедевр:
                  #define XML_GET_NAME(node) ((char *)((mxml_node_t *)(node)->value.element.name))
                  #define XML_GET_VALUE(node) ((char *)((mxml_node_t *)(node)->value.opaque))
                  Ответить
                  • Всё правильно сделано. Настоящие пацаны никогда не юзают документированные API! Только касты вслепую, только копание в деталях реализации, только хардкор!
                    Ответить
                    • А если бы покопались в недрах libmxml, знали бы что value.element.name и value.opaque - стринги и дополнительный каст не нужен.

                      ЕМНИП, в говномамонтной версии либы нормальных геттеров не было.
                      Ответить
                      • Но тип ноды то стоит проверить... Там ведь, судя по доке, не только opaque может оказаться... Или я перестраховываюсь?
                        Ответить
                        • Тип opaque будет только если использовать флаг MXML_OPAQUE_CALLBACK.
                          Ответить
          • > весь payload ограничен 4 КБ
            XML логирование по UDP поди?
            Ответить
            • Это для сообщений типа "Шеф, всё пропало". Основная часть перешла на TCP.
              Ответить
            • Зачем UDP? Чтобы мультикаст?
              Ответить
              • Чтобы не мучаться с поддержанием канала.
                Ответить
                • Всмысле "мучаться"?
                  Так сложно сделать реконнект?
                  Да и если канал постоянно рвется то половина логов просто протеряется
                  Ответить
                  • "Произошла ошибка переподключения во время логирования ошибки переподключения во время логирования ошибки XXX"
                    Ответить
                    • Зависит от ценности логов.
                      Можно и так:
                      1) положить в буфер
                      2) подождать N милисекунд
                      3) попробовать снова

                      Ну а если буфер переполница то старые выкидывать.

                      Система будет куда как надежнее.
                      -------
                      Но UDP зато можно стримить и собирать на 150 серверов независимо.
                      Куда-то то уж точно дойдет. А при наличии IGMP стримить можно и в другую сеть!
                      Ответить
                      • > Зависит от ценности логов.
                        В точку!
                        Ответить
                        • Ну да, ведь лог логу рознь.

                          1) логи для статистики (перформанс, кол-во юзерей, время ответа, загрузка CPU, какие-то факты для OLAP кубов-репортов итд). Часть таких логов можно продолбать и аппроксимировать.

                          2) логи секьюрити (например логин пользователя в систему или транзакция -- перевод миллиарда долларов на счет). Вот такие логи я бы не рискнул по UDP без подтверждения доставки;)
                          Ответить
                      • По UDP тоже можно сделать буферизованно-гарантированную доставку записей. Причём проще, надёжней и управляемей, чем по TCP :)
                        Ответить
                        • Как ганартировать что-то по UDP без самопального подтверждения?
                          Ответить
                          • Самопальным подтверждением.
                            Ответить
                            • Зачем оно, если есть тцп с подтверждением, окном и прочими блекджеками и шлюхами?
                              Ответить
                              • Затем, что для гарантированности доставки его и к TCP придётся привернуть. Никуда не денешься.

                                TCP гарантирует только порядок байт в потоке. Не более того.
                                Ответить
                                • Стоп! Под "гарантированностью доставки" я понимаю попадание данных в наше приложение (read() выполнился, или как-то так).
                                  Это вполне гарантирует TCP.
                                  Что неправильно?
                                  Ответить
                                  • То, что TCP не гарантирует попадания данных в приложение на другом конце канала. Старается, да. Но не более того.

                                    Гарантии TCP - порядок байт в потоке и их корректность.
                                    Ответить
                                    • Ну разумеется если провод порвался то TCP ничего не сделает, но оно поставит в известность об этом отправителя.
                                      А UDP не поставит.
                                      И кстати в случае порванного провода Вы никак не гарантируете.
                                      Ответить
                                      • > оно поставит в известность об этом отправителя
                                        Ну не поставит же. А если и поставит - то только по таймауту. И не скажет, какие именно байты проёбаны. Один хрен свои подтверждения прикручивать придётся. И, в итоге, мы получим окно поверх окна.

                                        > в случае порванного провода Вы никак не гарантируете
                                        В том и суть. Что гарантии у систем на основе TCP и UDP будут примерно одинаковые. Только с TCP, в данном случае, больше ёбли.
                                        Ответить
                                        • write() вернет -1.
                                          Значит, писун узнает что читун отвалился.
                                          Ответить
                                          • но не узнает, что он успел получить из буфера за это время, а что уже нет
                                            Ответить
                                            • да, это так. Это хендлят на более выскоих уровнях, видимо про это и говорил борманд
                                              Ответить
                                              • > Это хендлят на более выскоих уровнях
                                                Вот! И тут-то TCP, вместо того, чтобы помогать, начинает втыкать нам палки в колёса.
                                                Ответить
                                                • Вас не затруднит рассказать более развернуто КАК Вы предлагаете сделать максимально гарантированную доставку over UDP, и почему её лучше делать именно over UDP а не over TCP?
                                                  Ответить
                                                  • > КАК
                                                    Добавляем записи в "очередь" ограниченной длины. У каждой записи есть время переотправки (resend_time), ttl и priority. Поток отправляет записи с resend_time > now, при этом у записи увеличивается resend_time (по формуле, зависящей от ttl) и уменьшается ttl (если дошел до 0 - запись удаляется). При получении подтверждения соответствующие записи вычеркиваются из очереди. При переполнении очереди отбрасывается самая старая запись с priority <= приоритету вставляемой записи. Как-то так.

                                                    > а не over TCP
                                                    Потому, что буфера, таймауты и окна TCP тут будут только мешать (хотя, с другой стороны, на TCP мы получим лучший congestion control).
                                                    Ответить
                                                    • А разве нельзя в TCP выкрутить таймер и размер окна на подтверждение установить равным одной записи и получить тот же самый эффект?
                                                      Ответить
                                                      • > и получить тот же самый эффект
                                                        И зачем портить TCP, если можно улучшать UDP? :)
                                                        Ответить
                                                        • Чтобы писать меньше букв
                                                          Ответить
                                                          • > меньше
                                                            Ой ли?
                                                            Ответить
                                                            • Интуитивно кажется что да. Потому что достаточно взять TCP и поменять настройки. Кроме того мне неизвестны случаи использования самопального подтверждения по UDP: все, чему нужно подтверждение работает по TCP обычно, а миллионы мух не могут ошибаться!
                                                              Ответить
                                          • > write() вернет -1
                                            Святая наивность... Если кабель выдрать у писуна - да, вернет, скорее всего. В остальных случаях - просто пообещает записать N байт и отложит в буфер до поры до времени.
                                            Ответить
                                            • А если у читуна?)

                                              Ну хорошо, не сразу вернется, ОС какое-то время будет копить данные в буфере, потом на канальном уровне это будет хендлится (сетевуха будет пытаться что-то сделать итд). Но в конце концов -1 все-таки вернется же!
                                              Ответить
                                              • > Но в конце концов -1 все-таки вернется же!
                                                Если не крутить настройки сокета - через 20-30 минут. Только это будет уже совсем другой write().
                                                Ответить
                                                • Ох мне кажется это сильно зависит от нижних уровней.
                                                  Если например на роутере беда и пришел по ICMP "Destination unreachable" то всё равно ждать пол часа?)

                                                  А если пакеты летят вникуда и там дропаются то и правда ждать можно долго. Но кроме того есть настройки, как Вы правильно сказали.

                                                  Ну чудес не бывает же. Мы же не можем понять потерялся пакет навсегда или просто еще не пришел.
                                                  Ответить
                                                • Не знаю, я сетевую игру когда писал на чистом winsock через TCP, то выдёргивание кабеля сразу же становилось известным у всех. Правда, я не помню, у кого именно я выдёргивал кабель, вроде у обоих пытался.
                                                  Ответить
                                                  • > выдёргивание кабеля сразу же становилось известным у всех
                                                    Ну значит игра достаточно часто отправляла пакеты, и ICMP'шки хорошо пролезали...

                                                    А вот если выдрать кабель за каким-нибудь тупым коммутатором в локалке - скорее всего не узнают.
                                                    Ответить
                                        • Гарантий у TCP будет конечно же больше. Временные проблемы с сетью TCP решит вообще сам, переслав пачку пакетов. Серьезные проблемы он, конечно же, не решит.

                                          О какой ебле идет речь? TCP вполне себе реализован на большинстве платформ, тут ничего не надо пилить.

                                          Кроме того в TCP (ЕМНИП) ресивер может крутить окно и тем самым говорить посылальщику "быстрее-медленее", чтоб буфер не переполнился
                                          Ответить
    • Ответить
    • > Си
      > XML
      Блять.
      Ответить

    Добавить комментарий