• Erlang. Как правильно написать tcp server руководствуясь принципами otp?

    Slavenin999
    @Slavenin999 Автор вопроса
    Cам ковбой не использует сокеты напрямую, он идёт через ранчо https://github.com/ninenines/ranch ранчо же с одной стороны использует otp подход, но для обслуживания конкретных подключений использует модуль не на otp. Сделать таким образом было одним из обдумываемых вариантов, но в комментариях к статье (уже не найду где) описвающей такой подход было сказано, что это очень плохо и в otp все компоненты должны быть otp. Или всё-таки нет?
  • Как в doctrine 2 совместить innodb и myisam?

    Slavenin999
    @Slavenin999 Автор вопроса
    Мда, неожиданная подножка от доктрины... Придётся, видать, убирать индекс, благо, записей будет не более 3000. Благодарю.
  • Erlang. Как передать поток от одного процесса другому?

    Slavenin999
    @Slavenin999 Автор вопроса
    Или по другому: Aa знает pid O. Он обращается:
    gen_server:call(PidO, Msg),

    O вызывает gen_server:cast(PidB, { FromA, Msg })

    PidB делает gen_server:reply(From, Response)
    Результат возвращается в Aa.

    Работает! Большое спасибо!
  • Erlang. Как передать поток от одного процесса другому?

    Slavenin999
    @Slavenin999 Автор вопроса
    Я это прекрасно понимаю. Штука в том, что если вызывать do_work в контексте промежуточного процесса (О), то он точно также будет ждать ответа от Ба, а запросы к нему будут ставиться в очередь.
    c07bdbfb4bac4fe89d7c143a0c65319d.png итеряетяс весь смысл создания воркеров у Б, так как процесс всё-равно будет идти синхронно. Пример того, что должно получаться на картинке:
    b74aa46648fb44149933dc577d72c133.png при этом не важно как идут запросы, через Б или через промежуточный менеджер процессов О, главное, чтобы никто никого не ждал, кроме обращающегося к воркеру процесса.
  • Erlang. Как передать поток от одного процесса другому?

    Slavenin999
    @Slavenin999 Автор вопроса
    Реализовал вот такой вариант https://github.com/Slavenin/simple-server-with-workers но он не работает по вашей схеме. Почему не работает, понятно, из-за использования gen_server:cast/2. Использование gen_server:call/2 приведёт к остановке процесса супервизора до ответа воркера. Если использовать промежуточный процесс, то ситуация будет примерно такая же, только останавливаться будет промежуточный процесс. Основная же идея заключается в прямом связывании процессов Аа и Ба без остановки процессов, т.е. чтобы Аа ждал ответа от Ба, а всё остальное при этом работало. Буду благодарен за указание на то место, где я не прав.
  • Erlang. Как передать поток от одного процесса другому?

    Slavenin999
    @Slavenin999 Автор вопроса
    против такого аргумента не попрёшь :)
  • Erlang. Как передать поток от одного процесса другому?

    Slavenin999
    @Slavenin999 Автор вопроса
    За gen_server:reply(From, Answer) спасибо, не знал о такой возможности. Передать не проблема. Но я, скорее всего, пойду немного другим путём. Через метод в Б буду возвращать пид Ба, а из Аа по этому пиду работасть с Ба. Хотя ваш вариант тоже обязательно попробую, так как он позволяет не менять архитектуру.
  • C++, openssl как правильно сделать шифрование блоками?

    Slavenin999
    @Slavenin999 Автор вопроса
    Сделал поверку ничего не поменялось (может сделал что-то не то?). Кстати, под убунтой текст не расшифровывается сосвсем.
    консоль

    request is accepted
    param_par: action=encrypt
    param_par: text=my text for encrypt
    substr size is 16
    substr is my text for encr
    substr encr len is 16
    substr encr is :ve*Ǽ:my text for encr
    substr size is 3
    substr is ypt
    substr encr len is 16
    substr encr is
    PScFڽxypt
    use normal buffer
    final is :ve*Ǽ:
    PScFڽx$%3
    Try to accept new request
    request is accepted
    param_par: action=decrypt
    param_par: text=7jq4mxecsHZloMwqx7w6lakLUFOwsmNG2r3VFKB4D/QfxwijkOcan6KAJNzZJTPO

    unbase is :ve*Ǽ:
    PScFڽx$%3
    substr size is 16
    substr is :ve*Ǽ:
    substr decr len is 0
    :ve*Ǽ:_HcJϕx
    len is 0
    substr size is 16
    substr is
    PScFڽx
    substr decr len is 16
    vNi䗃J_HcJϕx
    len is 16
    substr size is 16
    substr is $%3
    substr decr len is 16
    substr decr is vNi䗃J(q%6NK_~
    len is 16
    use normal buffer
    3044924140:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:539:


    Большая благодарность за внимание к моей проблеме!
  • C++, openssl как правильно сделать шифрование блоками?

    Slavenin999
    @Slavenin999 Автор вопроса
    сделал, ошибка есть по-прежнему при дешифровании финального блока.
    2147144708:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:539:


    И
    e_param->data_len = chph.size()-1;
    тоже какая-то хрень. Зачем тут -1 ?

    осталось с предыдущих вариаций, когда e_param->data_len использовалось для определения размера расшифровываемого текста, без этого была ошибка о не верной длинне финального блока

    в статье используется запись параметра именно так как было у меня до этого. Возможно, проблема в чём-то другом? Например в ключах (для e_param->key испрользуется "my super secret key", для e_param->iv - "asdw@qwefas4654dfwert"), хотя пробовал хардкодить ключи из примера, ничего не поменялось.
  • C++, openssl как правильно сделать шифрование блоками?

    Slavenin999
    @Slavenin999 Автор вопроса
    Вы нигде не используете len который вам возвращает EVP_EncryptUpdate

    если я вас правильно понял, то использовать её нужно для определения размера возвращённых данных, так? Внёс изменение. Шифровать стало правильно. А вот при расшифровке проблема с последним блоком:
    лог

    param_par: action=decrypt
    param_par: text=nHWRj3u0l0783GSinxsEuDuaOgId/0S8/JGzmWEOUZ87mjoCHf9EvPyRs5lhDlGf
    unbase is u{Nd;:DaQ;:DaQ
    substr size is 16
    substr is u{Nd
    substr decr len is 0
    substr decr is my text for encr
    len is 0
    substr size is 16
    substr is ;:DaQmy text for encr
    substr decr len is 16
    substr decr is my text for encr
    len is 16
    2147144708:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:539:
    Aborted
    и почему-то считаете, что с out_buffer можно обращаться как с C-строкой (что неверно)

    подскажите пожалуйста, как правильно обращаться с out_buffer, чтобы получить правильный результат. Опирался на примеры отсюда
  • C++, openssl, fcgi что не так с функцией расшифровки?

    Slavenin999
    @Slavenin999 Автор вопроса
    >std::string::c_str возвращает const char *, эту строку нельзя модифицировать.
    убрал (странно, что нет ошибок)
    >e_param->result не инициализирован к этому моменту
    Я бы её инициализировал, но до расшифровки не известна длинна будущей строки, да и компилятор не ругается. А вообще если знаете как сделать правильнее, буду рад pull request`ам.
  • C++ как определить почему падает приложение?

    Slavenin999
    @Slavenin999 Автор вопроса
    Классная программа, благодарю. Но она не помогает понять почему в убунту не декодируется base64 строка. Если вывести переменную с результатом, то можно увидеть адрес указателя и пустое значение. Возможно, вы сможете подсказать в чём проблема unbase64 в файле function.cpp строка 211
  • C++ как определить почему падает приложение?

    Slavenin999
    @Slavenin999 Автор вопроса
    Функции перенёс, но проверить под виндой смогу только в понедельник, благодарю за наводку.
  • Как собрать приложение c++ с openssl?

    Slavenin999
    @Slavenin999 Автор вопроса
    ты тут не докопировал или как? должно быть -lcrypto вроде.

    Не дописал, хотя все команды я копировал с примеров (может устарели?)... В итоге, из терминала всё собирается, а из netbeans - нет, что в общем-то и пофиг, удобно конечно, но можно пока обойтись и без этого.
    Итого: рабочая команда для сборки получилась
    $ g++ function.cpp main.cpp -o my_openssl_use -I/usr/local/ssl/include/openssl/ -L/usr/local/ssl/lib/ -lssl -lcrypto

    победить netbeans пока не получилось, хотя и в этом уже продвинулся, флаг -o нельзя указывать в флагах компилятор, бинс сам его подставляет.
    Сейчас падает на
    g++ -I/usr/local/ssl/include/openssl/ -L/usr/local/ssl/lib/ -lssl -lcrypto   -c -g -Wall -MMD -MP -MF "build/Debug/Cygwin_4.x-Windows/function.o.d" -o build/Debug/Cygwin_4.x-Windows/function.o function.cpp
    mkdir -p build/Debug/Cygwin_4.x-Windows
    rm -f "build/Debug/Cygwin_4.x-Windows/main.o.d"
    g++ -I/usr/local/ssl/include/openssl/ -L/usr/local/ssl/lib/ -lssl -lcrypto   -c -g -Wall -MMD -MP -MF "build/Debug/Cygwin_4.x-Windows/main.o.d" -o build/Debug/Cygwin_4.x-Windows/main.o main.cpp
    mkdir -p dist/Debug/Cygwin_4.x-Windows
    g++ -I/usr/local/ssl/include/openssl/ -L/usr/local/ssl/lib/ -lssl -lcrypto    -o dist/Debug/Cygwin_4.x-Windows/encript build/Debug/Cygwin_4.x-Windows/function.o build/Debug/Cygwin_4.x-Windows/main.o 
    build/Debug/Cygwin_4.x-Windows/function.o: In function `Z14encript_scringRSs':
    function.cpp:36: undefined reference to `ERR_load_crypto_strings'
    function.cpp:37: undefined reference to `OPENSSL_add_all_algorithms_noconf'
    function.cpp:38: undefined reference to `OPENSSL_config'
    function.cpp:46: undefined reference to `BIO_dump_fp'
    function.cpp:60: undefined reference to `EVP_cleanup'
    function.cpp:61: undefined reference to `ERR_free_strings'
  • Как собрать приложение c++ с openssl?

    Slavenin999
    @Slavenin999 Автор вопроса
    g++ function.cpp main.cpp -o my_openssl_use -I -L/lib> -lssl -lcrypt

    сделал так:
    g++ function.cpp main.cpp -o my_openssl_use -I/usr/local/ssl/include/openssl/ -L/usr/local/ssl/lib/ -lssl -lcrypt

    ошибки
    /tmp/ccRPqfPB.o:function.cpp:(.text+0x1f): undefined reference to `ERR_load_crypto_strings'
    /tmp/ccRPqfPB.o:function.cpp:(.text+0x24): undefined reference to `OPENSSL_add_all_algorithms_noconf'
    /tmp/ccRPqfPB.o:function.cpp:(.text+0x30): undefined reference to `OPENSSL_config'
    /tmp/ccRPqfPB.o:function.cpp:(.text+0x92): undefined reference to `BIO_dump_fp'
    /tmp/ccRPqfPB.o:function.cpp:(.text+0xef): undefined reference to `EVP_cleanup'
    /tmp/ccRPqfPB.o:function.cpp:(.text+0xf4): undefined reference to `ERR_free_strings'
    /tmp/ccRPqfPB.o:function.cpp:(.text+0x110): undefined reference to `EVP_CIPHER_CTX_new'
    /tmp/ccRPqfPB.o:function.cpp:(.text+0x128): undefined reference to `EVP_aes_256_cbc'
    /tmp/ccRPqfPB.o:function.cpp:(.text+0x14d): undefined reference to `EVP_EncryptInit_ex'
    /tmp/ccRPqfPB.o:function.cpp:(.text+0x183): undefined reference to `EVP_EncryptUpdate'
    /tmp/ccRPqfPB.o:function.cpp:(.text+0x1b8): undefined reference to `EVP_EncryptFinal_ex'
    /tmp/ccRPqfPB.o:function.cpp:(.text+0x1d8): undefined reference to `EVP_CIPHER_CTX_free'
    /tmp/ccRPqfPB.o:function.cpp:(.text+0x1f2): undefined reference to `EVP_CIPHER_CTX_new'
    /tmp/ccRPqfPB.o:function.cpp:(.text+0x20a): undefined reference to `EVP_aes_256_cbc'
    /tmp/ccRPqfPB.o:function.cpp:(.text+0x22f): undefined reference to `EVP_DecryptInit_ex'
    /tmp/ccRPqfPB.o:function.cpp:(.text+0x265): undefined reference to `EVP_DecryptUpdate'
    /tmp/ccRPqfPB.o:function.cpp:(.text+0x29a): undefined reference to `EVP_DecryptFinal_ex'
    /tmp/ccRPqfPB.o:function.cpp:(.text+0x2ba): undefined reference to `EVP_CIPHER_CTX_free'
    /tmp/ccRPqfPB.o:function.cpp:(.text+0x2df): undefined reference to `ERR_print_errors_fp'
    /usr/lib/gcc/i686-pc-cygwin/4.8.2/../../../../i686-pc-cygwin/bin/ld: /tmp/ccRPqfPB.o: неправильный адрес перемещения 0x13 в разделе «.eh_frame»
    /usr/lib/gcc/i686-pc-cygwin/4.8.2/../../../../i686-pc-cygwin/bin/ld: final link failed: Неверная операция
    collect2: ошибка: выполнение ld завершилось с кодом возврата 1


    Может что-то собралось не верно? Запускаю всё из консоли cygwin
    Openssl собирал как
    ./config
    make
    make install
  • Как собрать приложение c++ с openssl?

    Slavenin999
    @Slavenin999 Автор вопроса
    netbeans генерит make файлы и потом по ним собирает проект
  • Как собрать приложение c++ с openssl?

    Slavenin999
    @Slavenin999 Автор вопроса
    g++ -m32 -o my_encrypt_app -L c:/cygwin/usr/local/ssl/lib/ -lssl -lcrypt   -c -g -I/cygdrive/c/cygwin/usr/local/ssl/include/ -MMD -MP -MF "build/Debug/Cygwin_4.x-Windows/function.o.d" -o build/Debug/Cygwin_4.x-Windows/function.o function.cpp
    cc1plus: fatal error: build/Debug/Cygwin_4.x-Windows/function.d: No such file or directory
  • Как собрать приложение c++ с openssl?

    Slavenin999
    @Slavenin999 Автор вопроса
    1) Убедись что openssl у тебя на машине установлен. Вместе с заголовочными файлами и библиотеками

    Установлен. В текущий момент собран через cygwin c помощью make
    (может нужно было какие-то флаги добавить?)
    2) Для того что бы собрать твой проект тебе нужно, что-то вроде этого

    после смены флагов:
    g++ -m32 -o my_encrypt_app -L c:/cygwin/usr/local/ssl/lib/ -lssl -lcrypt   -c -g -include /cygdrive/c/cygwin/usr/local/ssl/include/ -MMD -MP -MF "build/Debug/Cygwin_4.x-Windows/function.o.d" -o build/Debug/Cygwin_4.x-Windows/function.o function.cpp
    cc1plus: fatal error: build/Debug/Cygwin_4.x-Windows/function.d: No such file or directory
    compilation terminated.
  • Как собрать приложение c++ с openssl?

    Slavenin999
    @Slavenin999 Автор вопроса
    function.h
    #ifndef FUNCTION_H
    #define	FUNCTION_H
    #endif	/* FUNCTION_H */
    #include <openssl/conf.h>
    #include <openssl/evp.h>
    #include <openssl/err.h>
    #include <openssl/ssl.h>
    #include "openssl/bio.h"
    #include <string>
    
    using namespace std ;
    
    int encript_scring(string &);
    int encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key,
      unsigned char *iv, unsigned char *ciphertext);
    int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key,
      unsigned char *iv, unsigned char *plaintext);
    void handleErrors(void);
    function.cpp
    #include "function.h"
    #include <string.h>
    
    #define BUFSIZE 1024
    
    using namespace std;
    
    int encript_scring(string &data)
    {
    	/* Set up the key and iv. Do I need to say to not hard code these in a
    	 * real application? :-)
    	 */
    
    	/* A 256 bit key */
    	unsigned char *key = (unsigned char *)"01234567890123456789012345678901";
    
    	/* A 128 bit IV */
    	unsigned char *iv = (unsigned char *)"01234567890123456";
    
    	/* Message to be encrypted */
    	unsigned char *plaintext =
    			(unsigned char *)"The quick brown fox jumps over the lazy dog";
    
    	/* Buffer for ciphertext. Ensure the buffer is long enough for the
    	 * ciphertext which may be longer than the plaintext, dependant on the
    	 * algorithm and mode
    	 */
    	unsigned char ciphertext[128];
    
    	/* Buffer for the decrypted text */
    	unsigned char decryptedtext[128];
    
    	int decryptedtext_len, ciphertext_len;
    
    	/* Initialise the library */
    	ERR_load_crypto_strings();
    	OpenSSL_add_all_algorithms();
    	OPENSSL_config(NULL);
    
    	/* Encrypt the plaintext */
    	ciphertext_len = encrypt(plaintext, strlen((char *)plaintext), key, iv,
    			ciphertext);
    
    	/* Do something useful with the ciphertext here */
    	printf("Ciphertext is:\n");
    	BIO_dump_fp(stdout, (char *)ciphertext, ciphertext_len);
    
    	/* Decrypt the ciphertext */
    	decryptedtext_len = decrypt(ciphertext, ciphertext_len, key, iv,
    			decryptedtext);
    
    	/* Add a NULL terminator. We are expecting printable text */
    	decryptedtext[decryptedtext_len] = '\0';
    
    	/* Show the decrypted text */
    	printf("Decrypted text is:\n");
    	printf("%s\n", decryptedtext);
    
    	/* Clean up */
    	EVP_cleanup();
    	ERR_free_strings();
    
    
    	return 0;
    }
    
    int encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key,
      unsigned char *iv, unsigned char *ciphertext)
    {
      EVP_CIPHER_CTX *ctx;
    
      int len;
    
      int ciphertext_len;
    
      /* Create and initialise the context */
      if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();
    
      /* Initialise the encryption operation. IMPORTANT - ensure you use a key
       * and IV size appropriate for your cipher
       * In this example we are using 256 bit AES (i.e. a 256 bit key). The
       * IV size for *most* modes is the same as the block size. For AES this
       * is 128 bits */
      if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
        handleErrors();
    
      /* Provide the message to be encrypted, and obtain the encrypted output.
       * EVP_EncryptUpdate can be called multiple times if necessary
       */
      if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
        handleErrors();
      ciphertext_len = len;
    
      /* Finalise the encryption. Further ciphertext bytes may be written at
       * this stage.
       */
      if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) handleErrors();
      ciphertext_len += len;
    
      /* Clean up */
      EVP_CIPHER_CTX_free(ctx);
    
      return ciphertext_len;
    }
    
    int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key,
      unsigned char *iv, unsigned char *plaintext)
    {
      EVP_CIPHER_CTX *ctx;
    
      int len;
    
      int plaintext_len;
    
      /* Create and initialise the context */
      if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();
    
      /* Initialise the decryption operation. IMPORTANT - ensure you use a key
       * and IV size appropriate for your cipher
       * In this example we are using 256 bit AES (i.e. a 256 bit key). The
       * IV size for *most* modes is the same as the block size. For AES this
       * is 128 bits */
      if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
        handleErrors();
    
      /* Provide the message to be decrypted, and obtain the plaintext output.
       * EVP_DecryptUpdate can be called multiple times if necessary
       */
      if(1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
        handleErrors();
      plaintext_len = len;
    
      /* Finalise the decryption. Further plaintext bytes may be written at
       * this stage.
       */
      if(1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) handleErrors();
      plaintext_len += len;
    
      /* Clean up */
      EVP_CIPHER_CTX_free(ctx);
    
      return plaintext_len;
    }
    
    void handleErrors(void)
    {
      ERR_print_errors_fp(stderr);
      abort();
    }
    main.cpp
    /*
     * File:   main.cpp
     * Author: Максим
     *
     * Created on 7 мая 2014 г., 18:06
     */
    
    #include "function.h"
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <stdio.h>
    #include <cstdlib>
    #include <unistd.h>
    
    using namespace std ;
    
    int main()
    {
        int sock, listener;
    	int buf_size = 1024;
        struct sockaddr_in addr;
        char buf[buf_size];
        int bytes_read;
    	string msg("");
    	string encripted("");
    
        listener = socket(AF_INET, SOCK_STREAM, 0);
        if(listener < 0)
        {
            perror("socket");
            exit(1);
        }
    
        addr.sin_family = AF_INET;
        addr.sin_port = htons(3425);
        addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
        if(bind(listener, (struct sockaddr *)&addr, sizeof(addr)) < 0)
        {
            perror("bind");
            exit(2);
        }
    
        listen(listener, 1);
    
        while(1)
        {
            sock = accept(listener, NULL, NULL);
            if(sock < 0)
            {
                perror("accept");
                exit(3);
            }
    
            switch(fork())
            {
            case -1:
                perror("fork");
                break;
    
            case 0:
                close(listener);
                while(1)
                {
                    bytes_read = recv(sock, &buf, buf_size, 0);
    
    				msg.append(buf, 0, bytes_read);
                    if(bytes_read <= 0 || bytes_read <= buf_size)
    				{
    					encripted = encript_scring(msg);
    
    					//send(sock, msg.c_str(), msg.size(), 0);
    					close(listener);
    					close(sock);
    					break;
    				}
                }
    
                close(sock);
                _exit(0);
    
            default:
                close(sock);
            }
        }
    
        close(listener);
    
        return 0;
    }