LINUX.ORG.RU

Сообщения wolverin

 

nftables для FQDN

Форум — Admin

Приветствую.

Раз уж приходится переходить с iptables, которое сабж не умеет, на nftables появилась такая возможность?

 ,

wolverin
()

Ламбда в списке инициализации конструктора ?

Форум — Development

Приветствую.

Сначала написал многа букв в вопросе, но решил спросить просто кодом раз уж всегда требуют его - почему через обычный метод AutoCommit выполняется раньше всех и все работает, а через лямбду нет ибо порядок инициализации не соблюдается???

class CParamsTXT
{
private:
    const bool bAutoCommit;
    IBPP::Transaction tr;
    IBPP::Statement st;
    CDefFile * pCfg;
    const string Typ, Section, id_bank;

    bool getAutoCommit(IBPP::Transaction tr)
    {
fprintf(stderr, "\n111 111\n");
        const bool rt = !tr->Started();
        if (rt) tr->Start();
        return rt;
    }

protected:
    string GetParam(string & param, string Field, string Ident, string Default = "")
    { ... }

public:
    const string DateFormat, DatePoint, DecPoint, codepage;
    vector<string> svF;
    const char cNote;

    CParamsTXT(CDefFile * pCfg_, IBPP::Transaction tr_, IBPP::Statement st_, string Typ_, string Section_, string id_bank_, string DateFormat_, string DatePoint_, string DecPoint_, string codepage_, string Note_)
    :
        bAutoCommit([](IBPP::Transaction tr_){
fprintf(stderr, "\n111 222\n");
            const bool rt = !tr_->Started();
            if (rt) tr_->Start();
            return rt;}),
//      bAutoCommit(getAutoCommit(tr_)),
        tr(tr_), st(st_), pCfg(pCfg_),
        Typ(Typ_), Section(Section_), id_bank(id_bank_),
        DateFormat(GetParam(DateFormat_, "date_format", "DateFormat", "d/m/y")),
        DatePoint(GetParam(DatePoint_, "date_point", "DatePoint", "/")),
        DecPoint(GetParam(DecPoint_, "dec_point", "DecPoint", ".")),
        codepage(GetParam(codepage_, "codepage", "codepage", "DOS")),
        cNote(GetParam(Note_, "note", "NoteTXT", "")[0])
    { }

 

wolverin
()

DHCP не обновляет BIND9

Форум — Admin

Приветствую.

Очередная проблема после поднятия версии Debian c 8 до 10: isc-dhcp-server перестал обновлять локальную зону на шлюзе, из ошибок вижу такие сообщения

Nov 22 12:23:34 server dhcpd[]: DDNS: cleaning up lease pointer for a cancel cb=0x557dffa84800
Nov 22 12:23:34 server dhcpd[]: Unable to add forward map from имяхоста.имядомена.ru to 192.168.xxx.xxx: operation canceled

в бинде вообще тишина, никаких запросов нет

Делал конфиг когда то под Debian 6 конечно, но все работало пока не обновился

# grep -v ^# dhcpd.conf

ddns-update-style interim;
ddns-updates on;
ddns-domainname "имядомена.ru";
do-forward-updates on;
update-static-leases on;
ignore client-updates;
update-conflict-detection false;

include "/etc/dhcp/dhcpd.key";

zone имядомена.ru {
    primary 192.168.xxx.2;
    key DHCP_UPDATER;
}

zone xxx.168.192.in-addr.arpa {
    primary 192.168.xxx.2;
    key DHCP_UPDATER;
}

option domain-name "имядомена.ru";
option domain-name-servers 192.168.xxx.2;

option local-pac-server code 252 = text;
option local-pac-server "http://proxy/proxy.pac\000";

default-lease-time 36000;       # 10h
max-lease-time 86400;           # 24h

authoritative;

log-facility local7;

shared-network имясети {
    subnet 192.168.xxx.0 netmask 255.255.255.0 {
        range 192.168.xxx.10 192.168.xxx.250;
        option broadcast-address 192.168.xxx.255;
        option routers 192.168.xxx.2;
        option ntp-servers 192.168.xxx.2;
        filename "pxelinux.0";
        next-server 192.168.xxx.1;
    }
}

host имя1 {
    hardware ethernet 52:54:00:8b:xx:xx;
    fixed-address 192.168.xxx.xxx;
}

пока гуглеж не помогает, может кто сталкивался?

 ,

wolverin
()

Импорт ключей gpg

Форум — Admin

Приветствую.

После поднятия версии Debian c 8 до 10 перестали работать ключи, пытаюсь по новой их импортировать - пишет ошибку

$ gpg --import PUBRING.PGP
gpg: Всего обработано: 2
gpg:         пропущено ключей PGP-2: 2

Тут конечно написаны такие ужасы

Some algorithms and parts of the protocols as used by the 20 years old PGP-2 software are meanwhile considered unsafe.

With GnuPG 2.1 all support for those keys has gone.

но что конкретно нужно сделать в этой ситуации не соображу, буду очень благодарен любой помощи.

 

wolverin
()

libvirtd не грузится

Форум — Admin

Приветствую.

После поднятия версии Debian c 8 до 10 не запускается виртуалка с ошибкой

libvirtd[9019]: /usr/sbin/libvirtd: symbol lookup error: /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4: undefined symbol: libssh2_scp_recv2

либы стоят

# apt policy libssh2-1
libssh2-1:
  Установлен: 1.8.0-2.1+deb10u1
  Кандидат:   1.8.0-2.1+deb10u1
  Таблица версий:
 *** 1.8.0-2.1+deb10u1 500
        500 http://security.debian.org buster/updates/main amd64 Packages
        100 /var/lib/dpkg/status
     1.8.0-2.1 500
        500 http://mirror.yandex.ru/debian buster/main amd64 Packages

# apt policy libcurl3-gnutls
libcurl3-gnutls:
  Установлен: 7.64.0-4+deb10u7
  Кандидат:   7.64.0-4+deb10u7
  Таблица версий:
 *** 7.64.0-4+deb10u7 500
        500 http://security.debian.org buster/updates/main amd64 Packages
        100 /var/lib/dpkg/status
     7.64.0-4+deb10u2 500
        500 http://mirror.yandex.ru/debian buster/main amd64 Packages

гуглеж что то не помогает, подскажите в чем может быть проблема?

 ,

wolverin
()

Для чего alignas?

Форум — Development

Приветствую.

Про определение о требовании выравнивания читал конечно. Но таки как выбирается аргумент??? чтобы получить кучи прироста производительности )

Т.е. я например объявляю объекты как

alignas(64) std::atomic<size_t> tail;
alignas(64) std::atomic<size_t> head;

на xeon прирост в 2 раза, а на виртуалке можно считать погрешностью, но при 16 уже на виртуалке хоть и маленький, но таки -5% времени выполнения, при этом на процессоре падение.

 ,

wolverin
()

dkim pubkey_unavailable

Форум — Admin

приветствую.

савчера вдрух mail.ru начал мозги делать доставкой писем по поводу SPF, DKIM, DMARC

вроде все сделал по их инструкции https://help.mail.ru/postmaster/technical-settings/notes

добавил в bind9 3 записи вида

@       IN TXT "v=spf1 a mx ~all"
@       IN TXT "v=DKIM1; k=rsa; p=ПУБЛИЧНЫЙКЛЮЧ"
@       IN TXT "v=DMARC1; p=none"

поставил opendkim, прописал там соответственно место приватного ключа, в postfix сконфигрурировал на использование opendkim

один фих они пишут мне в заголовке

Authentication-Results: mxs.mail.ru; spf=pass (mx324.i.mail.ru: domain of ДОМЕН designates IPадрес as permitted sender) smtp.mailfrom=wolverin@ДОМЕН smtp.helo=mail.ДОМЕН;
	 dkim=invalid reason=pubkey_unavailable header.d=ДОМЕН
Received-SPF: pass (mx324.i.mail.ru: domain of ДОМЕН designates IPадрес as permitted sender) client-ip=IPадрес; envelope-from=wolverin@ДОМЕН; helo=mail.ДОМЕН;

DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=ДОМЕН; s=mail;
	t=1698894939; bh=JjZLfQmoespEUwGKuwbvnkkjWozy3SgKdtKb0xyF/W4=;
	h=Date:From:To:Subject:From;
	b=o+dgSgqvHNSmHZaJgs+9T6ErJ8sM8CMYLiaMRVgIZ4ED3hqE4yb/Vxy3x2j8Xb7qz
	 03wTwz4AFtmAR/UrSXjKSvCYiusvtSomimsWbUfvq/fNHhWZxLfQntnGEGO+RLTL+T
	 izuF0e1ptd/ZjmvrzBI5m9OZjQtoeLkLleP1vNLY=

User-Agent: Roundcube Webmail/1.2.3
X-DKIM-FAIL: DKIM test failed: invalid (address=wolverin@ДОМЕН domain=ДОМЕН reason=pubkey_unavailable).
X-Mailru-Src: mx
X-4EC0790: 10
X-6b629377: 1
X-7564579A: 646B95376F6C166E
X-77F55803: E822A06ED42C499A7F63DA2F9F2A54461ED951AC22C7845A9D1D1EE593088C900BBDAAE39103F3638701F0628C4B95CB650AB02DA031907FC423C6D7DB1CDA95F7F2529DD7A3558E4DF7BC4678047644
X-7FA49CB5: A9FCD207E66530D8A18204E546F3947C6807E7B3823913D9AFB8EE5BB20AF148C8A9BA7A39EFB7663CFE1401686631C009758206774B3CD2D5E8D9A59859A8B61831C2A8CBD9F7CA71492C2D3FF63AF69449624AB7ADAF37FD314BCFCDE4A234277E793F4B08E8842DAF2A56518EC330CC198E72ECD316A4BD9CCCA9EDD067B1FF0C04525729832C4E1E7243831EC1F578DA827A17800CE786D80B7E7735AB376320D30F47244B793CFE1401686631C082BFA309970D60C2B287FD4696A6DC2F5F5C1EE8F4F765FC04C22ED69F47F2D8B287FD4696A6DC2FA8DF7F3B2552694A4E2F5AFA99E116B42401471946AA11AF176DF2183F8FC7C086614E11AFA257BF8F08D7030A58E5ADC58D69EE07B1408453DF159EA87357C20A6AB1C7CE11FEE32FFDA4F57982C5F4B289B51CCB092ABD5571747095F342E8C234C8B12C006B7AAEC4162A2AA392DA8DFF822C4FED0E964788BA5126CA40DB8EEF46B7454FC60B9742502CCDD46D0DEDCF5861DED71B2F389733CBF5DBD5E913377AFFFEAFD269176DF2183F8FC7C078FCF50C7EAF9C588941B15DA834481FCF19DD082D7633A0EF3E4896CB9E6436389733CBF5DBD5E9D5E8D9A59859A8B601F8F2FECC0250C8CC7F00164DA146DA6F5DAA56C3B73B23E7726E8460B7C23C
X-C1DE0DAB: 0D63561A33F958A52EF6A6EFBDB43C8BA0F06EF541F76ED3AC0764A0D20A0778F87CCE6106E1FC07E67D4AC08A07B9B0A6C7FFFE744CA7FB9C5DF10A05D560A950611B66E3DA6D700B0A020F03D25A09EDCF5861DED71B2FF32E08699F8F45A1CDFF422315505062BA7CCD254A1CF5E833629329AA2D25E5
X-C8649E89: 1C3962B70DF3F0AD26C0D434D75DEB27F22D334B9B612B432CCB5A6D6581D03D0776B5B2C279835F17BCBE6708A5A68D02015372BE9702A20F84C43FA2038CDE3DE146DE6857D72CDEB7323C50A52AFEAC8CE95F42CF61090966F1585594D6159B815B7972F6FBBE7894B9023F5C129066BFC862880C174652EE4E5D9E54FDA44C41F94D744909CECE91D1F769AC3F588EBB7F9845D5049F9CB4C0EABAFD0B4C37E69C174A41D00C
X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr59cQFxbtK52nlS5dXYHM/vGJPPyhnCcOsWxjvstlFwfLDmG3SyZat9J5NbkWIjxq932/b2BQGyWkRn3AgzCpU/iMtBVD51WbvH0GkMdp0FX1YB//7MgRjFKDtzAHcKfpojwMUFqnUrer
X-F696D7D5: 1DeD6lt5UnY/fUsKeIs0lzdPoFv7BEpSOG24EIKoYNjqMV5tCw+fwA==

tcp порт 53 до бинда тоже открыл, так то письма ходят, но подскажите что этому майлу может быть еще нужно???

 

wolverin
()

Почему write(fd,..) висит?

Форум — Development

Приветствую

В продолжении темы Рестартануть драйвер как?

нашел как из консоли бесконечно количество раз рестартить драйвер

systemctl stop ***.service
echo spi0.0 > /sys/bus/spi/drivers/flexfb/unbind 
echo spi0.0 > /sys/bus/spi/drivers/flexfb/bind
systemctl start ***.service

делают тоже самое на сях как

static int setSPI(bool mode)
{
    const char
        * flexfb,
        spi[] = "spi0.0";

    if (mode)
    {
        flexfb = "/sys/bus/spi/drivers/flexfb/bind";
        fputs("Start spi device\n", stderr);
    }
    else
    {
        flexfb = "/sys/bus/spi/drivers/flexfb/unbind";
        fputs("Stop spi device\n", stdout);
    }

    int rt = -1;
    int fd = open(flexfb, O_WRONLY);
    if (fd > 0)
    {
        if ((rt = write(fd, spi, sizeof(spi))) <= 0)
            fprintf(stderr, "ERROR set SPI: %d %s [%s]\n", errno, strerror(errno), flexfb);
        close(fd);
    }
    else
        fprintf(stderr, "ERROR open %s: %d %s\n", flexfb, errno, strerror(errno));

    return rt;
}

уже без всяких systemctl просто запускаю и останавливаю приложение и в какой то момент на write(fd не снимаемая БЛОКИРОВКА

где может быть у меня косяк?

 , ,

wolverin
()

Рестартануть драйвер как?

Форум — Development

Приветствую

В продолжении темы Как рестартануть /dev/fb1 ???

как можно перезапустить из своего бинарника драйвер через ядро БЕЗ modprobe ???

 ,

wolverin
()

Как рестартануть /dev/fb1 ???

Форум — Linux-hardware

Приветствую.

Через /dev/fb1 с одноплатника реализовано подключение lcd экрана, который зараза по необъяснимым причинам иногда белеет.

Может есть способ не ребутить убунту для «сброса» внешнего устройства? В идеале бы еще узнать текущее состояние конечно.

Полагаю оно прячется где то в прерываниях, но как найти с которым связано?

cat /proc/interrupts
           CPU0       CPU1       CPU2       CPU3
 16:          0          0          0          0     GICv2  25 Level     vgic
 17:          0          0          0          0     GICv2  50 Level     /soc/timer@01c20c00
 18:          0          0          0          0     GICv2  29 Level     arch_timer
 19:   90547909  139451125  142656932  143202842     GICv2  30 Level     arch_timer
 20:          0          0          0          0     GICv2  27 Level     kvm guest timer
 22:          0          0          0          0     GICv2 120 Level     1ee0000.hdmi, dw-hdmi-cec
 24:          0          0          0          0     GICv2 118 Level     1c0c000.lcd-controller
 25:          0          0          0          0     GICv2  82 Level     1c02000.dma-controller
 26:         25          0          0          0     GICv2  92 Level     sunxi-mmc
 27:      79801          0          0          0     GICv2  94 Level     sunxi-mmc
 28:          1          0          0          0     GICv2 103 Level     musb-hdrc.4.auto
 29:          0          0          0          0     GICv2 104 Level     ehci_hcd:usb1
 30:          0          0          0          0     GICv2 105 Level     ohci_hcd:usb2
 31:          0          0          0          0     GICv2 106 Level     ehci_hcd:usb3
 32:          0          0          0          0     GICv2 107 Level     ohci_hcd:usb6
 33:          0          0          0          0     GICv2 108 Level     ehci_hcd:usb4
 34:          0          0          0          0     GICv2 109 Level     ohci_hcd:usb7
 35:   85647492          0          0          0     GICv2 110 Level     ehci_hcd:usb5
 36:          0          0          0          0     GICv2 111 Level     ohci_hcd:usb8
 39:     624264          0          0          0     GICv2  63 Level     1c25000.ths
 41:     305355          0          0          0     GICv2 114 Level     eth0
 42: 3951995844          0          0          0     GICv2  97 Level     sun6i-spi
 45:        432          0          0          0     GICv2  32 Level     ttyS0
 46:     177618          0          0          0     GICv2  33 Level     ttyS1
 49:          0          0          0          0     GICv2  38 Level     mv64xxx_i2c
 50:          0          0          0          0     GICv2  39 Level     mv64xxx_i2c
 51:          0          0          0          0     GICv2  40 Level     mv64xxx_i2c
 52:          0          0          0          0     GICv2  72 Level     1f00000.rtc
106:          1          0          0          0  sunxi_pio_edge  44 Edge      usb0-id-det
129:          1          0          0          0  sunxi_pio_edge   3 Edge      k1
IPI0:          0          0          0          0  CPU wakeup interrupts
IPI1:          0          0          0          0  Timer broadcast interrupts
IPI2:   90852252  258982397  266588110  269015295  Rescheduling interrupts
IPI3:        760        582        624        629  Function call interrupts
IPI4:          0          0          0          0  CPU stop interrupts
IPI5:      88146      26774      27729      28640  IRQ work interrupts
IPI6:          0          0          0          0  completion interrupts
Err:          0

 ,

wolverin
()

Линковка extern вместо передачи указателя в C и С++?

Форум — Development

Приветствую.

Вынес кусок кода в отдельный hpp, который использую в разных проектах. Из этого куска передаю указатель на метод в методы разного функционала скомпилированные в разных объектниках как на Сях, так и на С++

Все работает, НО можно ли сделать внешнее связывание одновременно как для Си, так и для С++ в одном проекте???

Например, я объявляю метод в разном функционале

для С++ в hpp просто как

extern void func(void * ptr)

для Си в секции

#ifdef __cplusplus
extern "C" {
#endif

extern void func(void * ptr)

#ifdef __cplusplus
}
#endif

Куски конечно компилируются, но при попытке собрать все это дело

MQTT.h:12:13: error: conflicting declaration of ‘void func(void*)’ with ‘C’ linkage
 extern void func(void * ptr);
             ^~~~~~~~~~~
In file included from IntercomIP.cpp:24:0:
SIP.hpp:36:13: note: previous declaration with ‘C++’ linkage
 extern void func(void * ptr);

По всякому уже попробовал ) Собирается только если будет как объектник выделенного кода, так и сам код включен в компиляцию бинарника, выглядит конечно это бредово.

 , , ,

wolverin
()

RTSP публикация надежна?

Форум — Development

Приветствую.

В чужом решении с тысячами железок, которое переписываю, схема предоставление видео реализована через видео rtsp прокси сервер (rtsp-simple-server) + openvpn до каждой железки с ее rtsp сервером - само собой что такая архитектура обладает некоторой сложностью и как следствие не высокой надежностью.

Поскольку пока нет возможности выпилить видео прокси, есть частично проверенная идея на железках «перевернуть» сервер, используя если не сам ffmpeg, то его либы, выполняя с железки пуш rtsp подключение.

В прошлом году удалось втащить старый ffserver с новыми либами ффмпега в свой проект, что дало по быстрому реализовать свой rtsp сервер, в который видео передаю как раз с помощью пуша ртсп между своими же потоками через локальный интерфейс - проблем не замечено, но тут это будет не в единичном случае, а тысячи таких подключений через ентернет, хоть сам rtsp-simple-server такой способ и поддерживает как я проверил.

Это бы дало мне отказ он vpn и части php функционала на проксе. Или может есть другие более надежные способы выкинуть VPN в такой схеме ???

 ,

wolverin
()

std::bad_function_call на указатель метода класса

Форум — Development

Приветствую.

В продолжении темы Вызов по указателю метода структуры вложенной в класс

Есть обработчик очереди класса в отдельном потоке

void CQueue::Handler(void)
{
    auto Get = [this](cmd_t & cmd) {
        std::unique_lock<std::mutex> ul(mtx);
        do {
            if (!abRun) return false;
        } while (!cv.wait_for(ul, std::chrono::seconds(1), [this]{ return !pq.empty(); }));

        cmd = pq.top();
        pq.pop();

        return true;
    };

    cmd_t cmd;
    while (Get(cmd))
        if (cmd.handle)
            (this->*(cmd.handle))(cmd.id, cmd.msg);
}

В саму очередь засовываю подобным образом из другого потока поступающих команд

pQ->Put(id, std::string(msg, msgLen), &CQueue::handle_pass);

частично описание класса

class CQueue
{
private:
    struct cmd_t {
        int8_t pri;
        std::string id, msg;
        void (CQueue::*handle)(const std::string & id, std::string & msg);
    };

    std::function<bool (const cmd_t &, const cmd_t &)> cmp = [](const cmd_t & l, const cmd_t & r){ return l.pri > r.pri; };

    std::priority_queue<cmd_t, std::vector<cmd_t>, decltype(cmp)> pq;

Все работает полагаю пока команды идут настолько «медленно», что CQueue::Handler успевает встать на условную переменную, но если удается за время вызова (this->(cmd.handle))(cmd.id, cmd.msg) засунуть в очередь несколько команд, то валится ошибка std::bad_function_call при вызове (this->(cmd.handle))

Разве нельзя одновременно передавать указатель на метод класса в другой поток и обращаться к нему???

 

wolverin
()

«без ключевое» шифрование конфига

Форум — Development

Приветствую

Есть куча железок на убунте (может будет расбиан), которые могут быть физически стырены, необходимо зашифровать конфиги моего ПО на них, да так чтобы ключ-пароль сей не светился в самом бинарнике.

Ранее пользовал штатную библиотеку libgcrypt с алгоритмом AES в режиме CBC, поэтому из мыслей брать пароль и соль, например, mac и uuid диска, но кажется это тривиальным

Посоветуйте как можно решить подобную задачу, в идеале «штатными» средствами.

 ,

wolverin
()

Вызов по указателю метода структуры вложенной в класс

Форум — Development

Приветствую.

Имеется класс вида

class CQueue
{
private:
    struct cmd_t {
        int8_t pri;
        std::string id, msg;
        void (CQueue::*handle)(const std::string & id, const std::string & msg);
    };
....
public:
    void handle_...(const std::string & id, const std::string & msg);
    void handle_push(const std::string & id, const std::string & msg);

int Put(const std::string & id, const std::string & msg, void (CQueue::*handle)(const std::string & id, const std::string & msg), const int8_t pri = 0);
void Handler(void);

из метода не этого класса добавляю в эту очередь и GCC не возмущается как

pQ->Put(id, std::string(msg, msgLen), &CQueue::handle_push);

а как теперь обратиться к этому методу внутри этого же класса??? думал должно быть что то вроде

void CQueue::Handler(void)
{
.....
    cmd_t cmd;
    while (Get(cmd))
        if (cmd.handle)
            (cmd.*handle)(cmd.id, cmd.msg);

но компилятор против, говорит нет никакого handle

так тоже пробовал и тут типы не совпадают

(cmd.*cmd.handle)(cmd.id, cmd.msg)

или вообще все это не правильно и надо городить на std::function ???

 

wolverin
()

Приоритетная очередь

Форум — Development

Приветствую

Через однопоточный обработчик поступают mqtt команды и его никак нельзя тормозить ещё и их обработкой, при этом какие то типы команд могут быть быстро обработаны, какие то существенно медленней.

Если с самой очередью приоритотов вроде есть понимание в использовании std::priority_queue (или лучше мудрить с heap???), то как организовать раздельную обработку каждого приоритета, чтобы длинные низкоприоритетные задачи не тормозили более высокие пока не соображу.

Пока только 2 вида, но может в будущем будет больше и не хочется тупо делать количество очередей просто по количеству приоритотов.

На чем такое реализовать на плюсах???

 

wolverin
()

Boost.Asio и несколько async_write/async_read за раз

Форум — Development

И снова здравствуйте! )

Получилось ПОЧТИ что хотел - за одно подключение-рукопожатие при пиковом (за время полного цикла от подключения до записи в сокет) поступлении команд через mqtt удается отправить херову гору rest-запросов, затем происходит отключение и ожидание следующей порции.

Но вот что нормально НЕ работает, так это CPush::handle_read_status, получаю туда после первого нормального response какой то мусор с периодической ошибкой от буста Operation canceled

Описание

class CPush
{
private:
    std::deque<std::string> dq;

    std::mutex mtx;
    std::condition_variable cv;

    boost::asio::ssl::stream<boost::asio::ip::tcp::socket> * psocket;

    std::string request;
    boost::asio::streambuf response;

    bool verify_certificate(bool preverified, boost::asio::ssl::verify_context & ctx);
    void handle_connect(const boost::system::error_code & error);
    void handle_handshake(const boost::system::error_code & error);
    void handle_write(const boost::system::error_code & error);
    void handle_read_status(const boost::system::error_code & error);
    void handle_read_header(const boost::system::error_code & error);
    void handle_read_content(const boost::system::error_code & error);

    void Write(void);
    int Get(std::string & http);

public:

    CPush(void) { std::cout << "PUSH client initialized" << std::endl; }

    int Put(const std::string & tokens, const std::string & cmd);

    bool Wait(void);
    void Handler(void);
};

Частично реализация

void CPush::handle_handshake(const boost::system::error_code & error)
{
    if (error)
        std::cerr << "Handshake failed: " << error.message() << std::endl;
    else
        Write();
}

void CPush::handle_write(const boost::system::error_code & error)
{
    if (error)
      std::cerr << "Write failed: " << error.message() << std::endl;
    else
    {
        std::cout << "Sending request OK!" << std::endl;

        boost::asio::async_read_until(*psocket,
                                response, "\r\n",
                                boost::bind(&CPush::handle_read_status,
                                            this,
                                            boost::asio::placeholders::error));

        Write();
    }
}

void CPush::handle_read_status(const boost::system::error_code & error)
{
    if (error)
        std::cout << "Error read status: " << error.message() << std::endl;
    else
    {
std::cout << "!!!!!!!!!!!!!!!!!!!\n" << &response << "\n!!!!!!!!!!!!!!!!!!!\n" << std::flush;
        // Check that response is OK.
        std::istream response_stream(&response);
        std::string http_version;
        response_stream >> http_version;
        unsigned int status_code;
        response_stream >> status_code;
        std::string status_message;
        std::getline(response_stream, status_message);


        if (!response_stream || http_version.substr(0, 5) != "HTTP/")
        {
            std::cout << "Invalid response\n";
            return;
        }

        if (status_code != 200)
        {
            std::cout << "Response returned with status code ";
            std::cout << status_code << "\n";
//          return;
        }

/*      // Read the response headers, which are terminated by a blank line.
        boost::asio::async_read_until(*psocket,
                                        response, "\r\n\r\n",
                                        boost::bind(&CPush::handle_read_header,
                                                    this,
                                                    boost::asio::placeholders::error));
*/    }
}

int CPush::Get(std::string & http)
{
    std::lock_guard<std::mutex> lock(mtx);

    int rt = dq.size();
    if (rt > 0)
    {
        http = dq.front();
        dq.pop_front();
    }

    return rt;
}

void CPush::Write(void)
{
    if (Get(request) > 0)
        boost::asio::async_write(*psocket,
                                boost::asio::buffer(request),
                                boost::bind(&CPush::handle_write,
                                            this,
                                            boost::asio::placeholders::error));
}

int CPush::Put(const std::string & tokens, const std::string & cmd)
{
    std::string json("{\"registration_ids\":[" + tokens + "],"
                    "\"notification\":null,"
....................
                    "\"priority\":\"high\","
                    "\"time_to_live\":15}");

    mtx.lock();

    dq.push_back("POST " + std::string(GOOGLE_API) + " HTTP/1.1\r\n"
                "Host: " + GOOGLE_HOST + "\r\n" // << ":" << port
                "Content-Type: application/json; charset=utf-8\r\n"
                "Content-Length: " + std::to_string(json.size()) + "\r\n"
                "Authorization: key=" + push_key + "\r\n\r\n" + json);
    int rt = dq.size();

    mtx.unlock();
    cv.notify_one();

    return rt;
}

bool CPush::Wait(void)
{
    std::unique_lock<std::mutex> ul(mtx);
    do {
        if (!abRun) return false;
    } while (!cv.wait_for(ul, std::chrono::seconds(1), [this]{ return dq.size() > 0; }));

    return true;
}

void CPush::Handler(void)
{
    boost::asio::io_service io_service;
    boost::asio::ip::tcp::resolver resolver(io_service);
    boost::asio::ip::tcp::resolver::query query(GOOGLE_HOST, GOOGLE_PORT);
    boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);

    boost::asio::ssl::context context(boost::asio::ssl::context::sslv23);
    context.set_default_verify_paths();

    boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket(io_service, context);
    socket.set_verify_mode(boost::asio::ssl::context::verify_none);
    socket.set_verify_callback(boost::bind(&CPush::verify_certificate, this, _1, _2));

    psocket = &socket;

    boost::asio::async_connect(psocket->lowest_layer(),
                                iterator,
                                boost::bind(&CPush::handle_connect,
                                            this,
                                            boost::asio::placeholders::error));

    io_service.run();
std::cout << "00000000000000000000000000000000000" << std::endl;
}

запускаю все это дело из основного потока

std::thread ([](void){ while (pPush->Wait()) pPush->Handler(); }).detach();

и добавляю команды из другого потока по событию

pPush->Put(tokens_, cmd_);

 , ,

wolverin
()

boost::asio::async_write вызывает Segmentation fault

Форум — Development

Приветствую.

Даже спрашивать уже опасаюсь, опять отдельные личности с большим самомнением начнут объяснять какой я тупой, но все таки попробую, вдруг кому не сложно )

Код класс ниже, теста ради из одного потока все работало, пока не решил вызвать CPush::Send из другого и все упало. Думал сначала что дело в std::stringstream request, которая была локальная - поднял ее до класса и не помогло.

Хоть намек бы к пониманию, где косяк, заранее спасибо за не равнодушие )

class CPush
{
private:
    std::stringstream request;

    boost::asio::io_service * pio_service;
    boost::asio::ssl::stream<boost::asio::ip::tcp::socket> * psocket;

    boost::asio::streambuf response;

bool verify_certificate(bool preverified, boost::asio::ssl::verify_context & ctx);
void handle_connect(const boost::system::error_code & error);
void handle_handshake(const boost::system::error_code & error);
void handle_write(const boost::system::error_code & error);//, size_t bytes_transferred
void handle_read_status(const boost::system::error_code & error);
void handle_read_header(const boost::system::error_code & error);
void handle_read_content(const boost::system::error_code & error);

public:

CPush(void){}

void LoopStart(void);
void LoopStop(void);
void Send(const std::string tokens, const std::string cmd);
};

Реализация

bool CPush::verify_certificate(bool preverified, boost::asio::ssl::verify_context & ctx)
{
    char subject_name[256];
    X509 * cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
    X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);

    std::cout << "Verifying " << subject_name << std::endl;

    return preverified;
}

void CPush::handle_connect(const boost::system::error_code & error)
{
    if (error)
        std::cerr << "Connect failed: " << error.message() << std::endl;
    else
    {
        // Support for Server Name Indication (SNI)
        SSL_set_tlsext_host_name(psocket->native_handle(), GOOGLE_HOST);

        psocket->async_handshake(boost::asio::ssl::stream_base::client,
                                boost::bind(&CPush::handle_handshake,
                                            this,
                                            boost::asio::placeholders::error));
        std::cout << "Connection OK!" << std::endl;
    }
}

void CPush::handle_handshake(const boost::system::error_code & error)
{
    if (error)
        std::cerr << "Handshake failed: " << error.message() << std::endl;
    else
    {  }
}

void CPush::handle_write(const boost::system::error_code & error)
{
    if (error)
      std::cerr << "Write failed: " << error.message() << std::endl;
    else
    {
        boost::asio::async_read_until(*psocket,
                                response, "\r\n",
                                boost::bind(&CPush::handle_read_status,
                                            this,
                                            boost::asio::placeholders::error));
        std::cout << "Sending request OK!" << std::endl;
    }
}

void CPush::handle_read_status(const boost::system::error_code & error)
{
    if (error)
        std::cout << "Error read status: " << error.message() << std::endl;
    else
    {
        // Check that response is OK.
        std::istream response_stream(&response);
        std::string http_version;
        response_stream >> http_version;
        unsigned int status_code;
        response_stream >> status_code;
        std::string status_message;
        std::getline(response_stream, status_message);

        if (!response_stream || http_version.substr(0, 5) != "HTTP/")
        {
            std::cout << "Invalid response\n";
            return;
        }

        if (status_code != 200)
        {
            std::cout << "Response returned with status code ";
            std::cout << status_code << "\n";
//          return;
        }

        // Read the response headers, which are terminated by a blank line.
        boost::asio::async_read_until(*psocket,
                                        response, "\r\n\r\n",
                                        boost::bind(&CPush::handle_read_header,
                                                    this,
                                                    boost::asio::placeholders::error));
    }
}

void CPush::handle_read_header(const boost::system::error_code & error)
{
    if (error)
        std::cout << "Error read header: " << error.message() << std::endl;
    else
    {
        // Process the response headers.
        std::istream response_stream(&response);
        std::string header;
        while (std::getline(response_stream, header) && header != "\r")
            std::cout << header << "\n";
        std::cout << "\n";

        // Write whatever content we already have to output.
        if (response.size() > 0)
            std::cout << &response;

        // Start reading remaining data until EOF.
        boost::asio::async_read(*psocket,
                                response,
                                boost::asio::transfer_at_least(1),
                                boost::bind(&CPush::handle_read_content,
                                            this,
                                            boost::asio::placeholders::error));
    }
}

void CPush::handle_read_content(const boost::system::error_code & error)
{
    if (error)
    {
        if (error != boost::asio::error::eof)
            std::cout << "Error read content: " << error.message() << std::endl;
    }
    else
    {
        // Write all of the data that has been read so far.
        std::cout << &response;

        // Continue reading remaining data until EOF.
        boost::asio::async_read(*psocket,
                                response,
                                boost::asio::transfer_at_least(1),
                                boost::bind(&CPush::handle_read_content,
                                            this,
                                            boost::asio::placeholders::error));
    }
}

void CPush::LoopStart(void)
{
    boost::asio::io_service io_service;
    boost::asio::ip::tcp::resolver resolver(io_service);
    boost::asio::ip::tcp::resolver::query query(GOOGLE_HOST, GOOGLE_PORT);
    boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);

    boost::asio::ssl::context context(boost::asio::ssl::context::sslv23);
    context.set_default_verify_paths();

    boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket(io_service, context);
    socket.set_verify_mode(boost::asio::ssl::context::verify_none);
    socket.set_verify_callback(boost::bind(&CPush::verify_certificate, this, _1, _2));

    psocket = &socket;
    pio_service = &io_service;

    boost::asio::async_connect(psocket->lowest_layer(),
                                iterator,
                                boost::bind(&CPush::handle_connect,
                                            this,
                                            boost::asio::placeholders::error));

    io_service.run();
}

void CPush::Send(const std::string tokens, const std::string cmd)
{
    std::string json("{\"registration_ids\":[" + tokens + "],"
                    "\"notification\":null,"
....
                    "\"priority\":\"high\","
                    "\"time_to_live\":15}");

    request << "POST " << GOOGLE_API << " HTTP/1.1\r\n"
            << "Host: " << GOOGLE_HOST << "\r\n" // << ":" << port
            << "Content-Type: application/json; charset=utf-8\r\n"
            << "Content-Length: " << json.size() << "\r\n"
            << "Authorization: key=" << push_key << "\r\n"
            << "\r\n"
            << json;

    std::cout << "Sending request...\n" << request.str() << std::endl;

    boost::asio::async_write(*psocket,
                            boost::asio::buffer(request.str()),
                            boost::bind(&CPush::handle_write,
                                        this,
                                        boost::asio::placeholders::error));
}

void CPush::LoopStop(void)
{
    if (!pio_service->stopped()) pio_service->stop();
}

 , ,

wolverin
()

openssl не выполняет рукопожатие

Форум — Admin

Приветствую

Почему может не выполняться проверка сертификатов сервера???

Пробовал так

openssl s_client -connect fcm.googleapis.com:443

на одном дебиане выхлоп корректный

CONNECTED(00000003)
depth=2 C = US, O = Google Trust Services LLC, CN = GTS Root R1
verify return:1
depth=1 C = US, O = Google Trust Services LLC, CN = GTS CA 1C3
verify return:1
depth=0 CN = *.google.com
verify return:1
---
Certificate chain
 0 s:/CN=*.google.com
   i:/C=US/O=Google Trust Services LLC/CN=GTS CA 1C3
 1 s:/C=US/O=Google Trust Services LLC/CN=GTS CA 1C3
   i:/C=US/O=Google Trust Services LLC/CN=GTS Root R1
 2 s:/C=US/O=Google Trust Services LLC/CN=GTS Root R1
   i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIPBzCCDe+gAwIBAgIQKuaFLS3w+z4K/anwgexsvTANBgkqhkiG9w0BAQsFADBG
MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM
QzETMBEGA1UEAxMKR1RTIENBIDFDMzAeFw0yMzA3MTcwODE2MzFaFw0yMzEwMDkw
ODE2MzBaMBcxFTATBgNVBAMMDCouZ29vZ2xlLmNvbTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAMfBborGk6pXdukFvjev59Vz+nq4XsLmbYMMDQEtmSui
8wKv5LP9FxeOa4KyRJbGPajaCXFkV9wkMl5yrTY93bZ5uwMZDORRzUWylxwHlZxN
ks0/Jvjp/gUKtc+K0z5WxOnkq5V+rNpjMr6I6W0UAHHLqS+FjyKCV5b5qA2Jadz9
nvv3ddO6OuA1ozx/wGLY2j2k/27cl4ep6DbK8gDURrciy7zSzAsz1cFUBzAUEfpw
em2YppjmzCuey22gYHuFsXB5k4rzTSu9gwx3A6wooIsg54R+csY3dyNHvisWuC7w
2VlEQ87PeCshOWCfdoIxoSNeeQOmFAp5vhbo5DvDRD0CAwEAAaOCDB4wggwaMA4G
A1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAA
MB0GA1UdDgQWBBQZ48UsKZ0bzHsEYfPyvXkC+xbu1jAfBgNVHSMEGDAWgBSKdH+v
hc3ulc09nNDiRhTzcTUdJzBqBggrBgEFBQcBAQReMFwwJwYIKwYBBQUHMAGGG2h0
dHA6Ly9vY3NwLnBraS5nb29nL2d0czFjMzAxBggrBgEFBQcwAoYlaHR0cDovL3Br
aS5nb29nL3JlcG8vY2VydHMvZ3RzMWMzLmRlcjCCCc0GA1UdEQSCCcQwggnAggwq
Lmdvb2dsZS5jb22CFiouYXBwZW5naW5lLmdvb2dsZS5jb22CCSouYmRuLmRldoIV
Ki5vcmlnaW4tdGVzdC5iZG4uZGV2ghIqLmNsb3VkLmdvb2dsZS5jb22CGCouY3Jv
d2Rzb3VyY2UuZ29vZ2xlLmNvbYIYKi5kYXRhY29tcHV0ZS5nb29nbGUuY29tggsq
Lmdvb2dsZS5jYYILKi5nb29nbGUuY2yCDiouZ29vZ2xlLmNvLmlugg4qLmdvb2ds
ZS5jby5qcIIOKi5nb29nbGUuY28udWuCDyouZ29vZ2xlLmNvbS5hcoIPKi5nb29n
bGUuY29tLmF1gg8qLmdvb2dsZS5jb20uYnKCDyouZ29vZ2xlLmNvbS5jb4IPKi5n
b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20udHKCDyouZ29vZ2xlLmNvbS52boIL
Ki5nb29nbGUuZGWCCyouZ29vZ2xlLmVzggsqLmdvb2dsZS5mcoILKi5nb29nbGUu
aHWCCyouZ29vZ2xlLml0ggsqLmdvb2dsZS5ubIILKi5nb29nbGUucGyCCyouZ29v
Z2xlLnB0ghIqLmdvb2dsZWFkYXBpcy5jb22CDyouZ29vZ2xlYXBpcy5jboIRKi5n
b29nbGV2aWRlby5jb22CDCouZ3N0YXRpYy5jboIQKi5nc3RhdGljLWNuLmNvbYIP
Z29vZ2xlY25hcHBzLmNughEqLmdvb2dsZWNuYXBwcy5jboIRZ29vZ2xlYXBwcy1j
bi5jb22CEyouZ29vZ2xlYXBwcy1jbi5jb22CDGdrZWNuYXBwcy5jboIOKi5na2Vj
bmFwcHMuY26CEmdvb2dsZWRvd25sb2Fkcy5jboIUKi5nb29nbGVkb3dubG9hZHMu
Y26CEHJlY2FwdGNoYS5uZXQuY26CEioucmVjYXB0Y2hhLm5ldC5jboIQcmVjYXB0
Y2hhLWNuLm5ldIISKi5yZWNhcHRjaGEtY24ubmV0ggt3aWRldmluZS5jboINKi53
aWRldmluZS5jboIRYW1wcHJvamVjdC5vcmcuY26CEyouYW1wcHJvamVjdC5vcmcu
Y26CEWFtcHByb2plY3QubmV0LmNughMqLmFtcHByb2plY3QubmV0LmNughdnb29n
bGUtYW5hbHl0aWNzLWNuLmNvbYIZKi5nb29nbGUtYW5hbHl0aWNzLWNuLmNvbYIX
Z29vZ2xlYWRzZXJ2aWNlcy1jbi5jb22CGSouZ29vZ2xlYWRzZXJ2aWNlcy1jbi5j
b22CEWdvb2dsZXZhZHMtY24uY29tghMqLmdvb2dsZXZhZHMtY24uY29tghFnb29n
bGVhcGlzLWNuLmNvbYITKi5nb29nbGVhcGlzLWNuLmNvbYIVZ29vZ2xlb3B0aW1p
emUtY24uY29tghcqLmdvb2dsZW9wdGltaXplLWNuLmNvbYISZG91YmxlY2xpY2st
Y24ubmV0ghQqLmRvdWJsZWNsaWNrLWNuLm5ldIIYKi5mbHMuZG91YmxlY2xpY2st
Y24ubmV0ghYqLmcuZG91YmxlY2xpY2stY24ubmV0gg5kb3VibGVjbGljay5jboIQ
Ki5kb3VibGVjbGljay5jboIUKi5mbHMuZG91YmxlY2xpY2suY26CEiouZy5kb3Vi
bGVjbGljay5jboIRZGFydHNlYXJjaC1jbi5uZXSCEyouZGFydHNlYXJjaC1jbi5u
ZXSCHWdvb2dsZXRyYXZlbGFkc2VydmljZXMtY24uY29tgh8qLmdvb2dsZXRyYXZl
bGFkc2VydmljZXMtY24uY29tghhnb29nbGV0YWdzZXJ2aWNlcy1jbi5jb22CGiou
Z29vZ2xldGFnc2VydmljZXMtY24uY29tghdnb29nbGV0YWdtYW5hZ2VyLWNuLmNv
bYIZKi5nb29nbGV0YWdtYW5hZ2VyLWNuLmNvbYIYZ29vZ2xlc3luZGljYXRpb24t
Y24uY29tghoqLmdvb2dsZXN5bmRpY2F0aW9uLWNuLmNvbYIkKi5zYWZlZnJhbWUu
Z29vZ2xlc3luZGljYXRpb24tY24uY29tghZhcHAtbWVhc3VyZW1lbnQtY24uY29t
ghgqLmFwcC1tZWFzdXJlbWVudC1jbi5jb22CC2d2dDEtY24uY29tgg0qLmd2dDEt
Y24uY29tggtndnQyLWNuLmNvbYINKi5ndnQyLWNuLmNvbYILMm1kbi1jbi5uZXSC
DSouMm1kbi1jbi5uZXSCFGdvb2dsZWZsaWdodHMtY24ubmV0ghYqLmdvb2dsZWZs
aWdodHMtY24ubmV0ggxhZG1vYi1jbi5jb22CDiouYWRtb2ItY24uY29tghRnb29n
bGVzYW5kYm94LWNuLmNvbYIWKi5nb29nbGVzYW5kYm94LWNuLmNvbYIeKi5zYWZl
bnVwLmdvb2dsZXNhbmRib3gtY24uY29tgg0qLmdzdGF0aWMuY29tghQqLm1ldHJp
Yy5nc3RhdGljLmNvbYIKKi5ndnQxLmNvbYIRKi5nY3BjZG4uZ3Z0MS5jb22CCiou
Z3Z0Mi5jb22CDiouZ2NwLmd2dDIuY29tghAqLnVybC5nb29nbGUuY29tghYqLnlv
dXR1YmUtbm9jb29raWUuY29tggsqLnl0aW1nLmNvbYILYW5kcm9pZC5jb22CDSou
YW5kcm9pZC5jb22CEyouZmxhc2guYW5kcm9pZC5jb22CBGcuY26CBiouZy5jboIE
Zy5jb4IGKi5nLmNvggZnb28uZ2yCCnd3dy5nb28uZ2yCFGdvb2dsZS1hbmFseXRp
Y3MuY29tghYqLmdvb2dsZS1hbmFseXRpY3MuY29tggpnb29nbGUuY29tghJnb29n
bGVjb21tZXJjZS5jb22CFCouZ29vZ2xlY29tbWVyY2UuY29tgghnZ3BodC5jboIK
Ki5nZ3BodC5jboIKdXJjaGluLmNvbYIMKi51cmNoaW4uY29tggh5b3V0dS5iZYIL
eW91dHViZS5jb22CDSoueW91dHViZS5jb22CFHlvdXR1YmVlZHVjYXRpb24uY29t
ghYqLnlvdXR1YmVlZHVjYXRpb24uY29tgg95b3V0dWJla2lkcy5jb22CESoueW91
dHViZWtpZHMuY29tggV5dC5iZYIHKi55dC5iZYIaYW5kcm9pZC5jbGllbnRzLmdv
b2dsZS5jb22CG2RldmVsb3Blci5hbmRyb2lkLmdvb2dsZS5jboIcZGV2ZWxvcGVy
cy5hbmRyb2lkLmdvb2dsZS5jboIYc291cmNlLmFuZHJvaWQuZ29vZ2xlLmNuMCEG
A1UdIAQaMBgwCAYGZ4EMAQIBMAwGCisGAQQB1nkCBQMwPAYDVR0fBDUwMzAxoC+g
LYYraHR0cDovL2NybHMucGtpLmdvb2cvZ3RzMWMzL2ZWSnhiVi1LdG1rLmNybDCC
AQUGCisGAQQB1nkCBAIEgfYEgfMA8QB2AK33vvp8/xDIi509nB4+GGq0Zyldz7EM
JMqFhjTr3IKKAAABiWMjJUEAAAQDAEcwRQIgOupe5IIvifbm8xiVlqEyhOBpvXTC
Mkvs+996tP8raj8CIQCC+C7j+83WcIXUnzjdW8wwN/3P0uNF49pPBTmResO+tQB3
ALNzdwfhhFD4Y4bWBancEQlKeS2xZwwLh9zwAw55NqWaAAABiWMjJR8AAAQDAEgw
RgIhAO1LcKXKCSglGWIo/8XcwE5dKrcyqmyZzjcq1+ybZaL9AiEArfqI2WkZqy6M
eHLLDw1hPAmLc6DsJ13iUTkIEq6XvaUwDQYJKoZIhvcNAQELBQADggEBAHfeJw06
wBei3Xl0+77k+p0jn5wWWVXpEzDiRdaJZsJy/29lWzgGaNNDU8/kYDtoEFvOaaun
WqrrkJSDLHGooerEGWBuPo57trL7W6ZeRVn4BEogjk6lgz5w7As6IEdGiz2kZNEp
saJVgbfkdHpVIsiXJBAKSD9gXbI58bxHtIMFAYd9LwwvG4P3yFnPoYiRhKXMBuWl
i906cqjelyUG4kjB+AwDcD837QDZC78fGLDwW9NsdwYyKgY2kBdbleeRwyXtigvw
IabvTdvYKuTK8R0l+DSMz6oKS9F2IU2QDTyO1CXGPU1mYQPmtV714sdzq3r9gZmP
rktC22JuuTQfLVs=
-----END CERTIFICATE-----
subject=/CN=*.google.com
issuer=/C=US/O=Google Trust Services LLC/CN=GTS CA 1C3
---
No client certificate CA names sent
Peer signing digest: SHA256
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 7357 bytes and written 261 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ECDHE-RSA-CHACHA20-POLY1305
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-CHACHA20-POLY1305
    Session-ID: 6729DCD94FC7F482C061EBA85C6925EBBD3825F91A40308F66BE77408BDE82D3
    Session-ID-ctx:
    Master-Key: A6A142D3777B88391EF8FCDBF83251658DD54178E49FA90D4E19D940BBCC8976BEEFE8AEC4445BD65B9B1232258E91F9
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 100800 (seconds)
    TLS session ticket:
    0000 - 02 f4 dc 2a b0 9d 9e d3-84 56 19 15 ff 1c 8d eb   ...*.....V......
    0010 - 19 65 dc 84 fe c9 6a 7b-fe 89 44 6a e7 88 0f 20   .e....j{..Dj...
    0020 - 6c fa 03 b3 3d b6 0c f0-85 09 2a 26 a5 99 9f 25   l...=.....*&...%
    0030 - fa c3 0b 3d 56 58 96 95-1a 55 96 da 3b 90 07 bc   ...=VX...U..;...
    0040 - 66 54 e8 b7 ad 0d ef b6-9b ff 61 d4 34 f6 6e 03   fT........a.4.n.
    0050 - 3c 19 36 f7 6a fd 77 cf-b1 86 48 93 15 88 d7 40   <.6.j.w...H....@
    0060 - 7b 4d 5b 00 7f 44 ca c8-a9 d0 a3 31 5b e1 b7 2f   {M[..D.....1[../
    0070 - 5a 4e d9 8c e5 69 0b 18-ec 99 45 3a 54 16 f0 39   ZN...i....E:T..9
    0080 - cf 89 de 8d d5 3d 11 0b-e4 04 4e 54 46 a5 fe f8   .....=....NTF...
    0090 - db e9 57 49 c4 c1 b7 9a-84 fe 61 dc b5 bd 13 ed   ..WI......a.....
    00a0 - 2e 08 4e bb b0 f5 b7 d0-ec ae 63 59 1c 0b c7 96   ..N.......cY....
    00b0 - 43 33 2c d3 9e a7 bb b9-5b 30 57 36 a5 c3 b6 12   C3,.....[0W6....
    00c0 - 8e f1 e3 7a d0 fd f7 22-cc bf 1b c1 df f7 22 33   ...z..."......"3
    00d0 - 10 83 e6 3e cc c6 28 b6-c8 d8 4c 50 50 32 52 0d   ...>..(...LPP2R.
    00e0 - 2f 4c 31 d3 14                                    /L1..

    Start Time: 1691473119
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: yes
---
read:errno=0

на другом вижу только висящее

CONNECTED(00000003)

 

wolverin
()

REST через Boost.Asio

Форум — Development

Приветствую

Подскажите где у меня косяк, а смотрю в документацию - вижу фигу

Вызов Send(), чернового варианта класса описанного ниже, выполняется только один раз, в чем косяк у меня, а то смотрю в документацию - вижу фигу.

class CPush
{
private:
    boost::asio::io_service io_service;
    boost::asio::ip::tcp::resolver::iterator iterator;
    boost::asio::ssl::stream<boost::asio::ip::tcp::socket> * psocket;
    boost::asio::streambuf response;

bool verify_certificate(bool preverified, boost::asio::ssl::verify_context & ctx)
{
    char subject_name[256];
    X509 * cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
    X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);

    std::cout << "Verifying " << subject_name << std::endl;

    return preverified;
}

void handle_connect(const boost::system::error_code & error)
{
    if (error)
        std::cerr << "Connect failed: " << error.message() << std::endl;
    else
    {
        psocket->async_handshake(boost::asio::ssl::stream_base::client,
                                boost::bind(&CPush::handle_handshake,
                                            this,
                                            boost::asio::placeholders::error));
        std::cout << "Connection OK!" << std::endl;
    }
}

void handle_handshake(const boost::system::error_code & error)
{
    if (error)
        std::cerr << "Handshake failed: " << error.message() << std::endl;
    else
    {
        std::string json("{\"registration_ids\":[\"" + token + "\"],"
                        +"\"notification\":null,"
.......
                        +"\"priority\":\"high\","
                        +"\"time_to_live\":15}");

        std::stringstream request;
        request << "POST " << GOOGLE_API << " HTTP/1.1\r\n"
                << "Host: " << GOOGLE_HOST << "\r\n" // << ":" << GOOGLE_PORT
                << "Content-Type: application/json; charset=utf-8\r\n"
                << "Content-Length: " << json.size() << "\r\n"
                << "Authorization: key=" << push_key << "\r\n"
                << "Connection: close\r\n"
                << "\r\n"
                << json << "\r\n\r\n";

        std::cout << "Sending request...\n" << request.str();


        boost::asio::async_write(*psocket,
                                boost::asio::buffer(request.str()),
                                boost::bind(&CPush::handle_write,
                                            this,
                                            boost::asio::placeholders::error));
    }
}

void handle_write(const boost::system::error_code & error)
{
    if (error)
      std::cerr << "Write failed: " << error.message() << std::endl;
    else
    {
        boost::asio::async_read_until(*psocket,
                                response, "\r\n",
                                boost::bind(&CPush::handle_read_status,
                                            this,
                                            boost::asio::placeholders::error));
        std::cout << "Sending request OK!" << std::endl;
    }
}

void handle_read_status(const boost::system::error_code & error)
{
    if (error)
        std::cout << "Error read status: " << error.message() << std::endl;
    else
    {
        // Check that response is OK.
        std::istream response_stream(&response);
        std::string http_version;
        response_stream >> http_version;
        unsigned int status_code;
        response_stream >> status_code;
        std::string status_message;
        std::getline(response_stream, status_message);

        if (!response_stream || http_version.substr(0, 5) != "HTTP/")
        {
            std::cout << "Invalid response\n";
            return;
        }

        if (status_code != 200)
        {
            std::cout << "Response returned with status code ";
            std::cout << status_code << "\n";
//          return;
        }

        // Read the response headers, which are terminated by a blank line.
        boost::asio::async_read_until(*psocket,
                                        response, "\r\n\r\n",
                                        boost::bind(&CPush::handle_read_header,
                                                    this,
                                                    boost::asio::placeholders::error));
    }
}

void handle_read_header(const boost::system::error_code & error)
{
    if (error)
        std::cout << "Error read header: " << error.message() << std::endl;
    else
    {
        // Process the response headers.
        std::istream response_stream(&response);
        std::string header;
        while (std::getline(response_stream, header) && header != "\r")
            std::cout << header << "\n";
        std::cout << "\n";

        // Write whatever content we already have to output.
        if (response.size() > 0)
            std::cout << &response;

        // Start reading remaining data until EOF.
        boost::asio::async_read(*psocket,
                                response,
                                boost::asio::transfer_at_least(1),
                                boost::bind(&CPush::handle_read_content,
                                            this,
                                            boost::asio::placeholders::error));
    }
}

void handle_read_content(const boost::system::error_code & error)
{
    if (error)
    {
        if (error != boost::asio::error::eof)
            std::cout << "Error read content: " << error.message() << std::endl;
    }
    else
    {
        // Write all of the data that has been read so far.
        std::cout << &response;

        // Continue reading remaining data until EOF.
        boost::asio::async_read(*psocket,
                                response,
                                boost::asio::transfer_at_least(1),
                                boost::bind(&CPush::handle_read_content,
                                            this,
                                            boost::asio::placeholders::error));
    }
}

public:

CPush(void)
{

    boost::asio::ip::tcp::resolver resolver(io_service);
    boost::asio::ip::tcp::resolver::query query(GOOGLE_HOST, GOOGLE_PORT);
    iterator = resolver.resolve(query);

    boost::asio::ssl::context context(boost::asio::ssl::context::sslv23);
    context.set_default_verify_paths();

    psocket = new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(io_service, context);
    psocket->set_verify_mode(boost::asio::ssl::context::verify_none);
    psocket->set_verify_callback(boost::bind(&CPush::verify_certificate, this, _1, _2));
}

void Send(void)
{
    boost::asio::async_connect(psocket->lowest_layer(),
                                iterator,
                                boost::bind(&CPush::handle_connect,
                                            this,
                                            boost::asio::placeholders::error));

    io_service.run();
}
};

 , ,

wolverin
()

RSS подписка на новые темы