2016-03-23 2 views
2

zmqとzmqppでは、メタデータとそれが属するメッセージを転送する方法を探しています。目標は、セキュアソケットを所有するロードバランサの背後にある作業者に「User-Id」を取得することです。zeromq/zmqpp:メッセージでのメタデータの転送

ここでは単純な例を示します。転送後にメタデータが消えるのがわかります。私は確信していません:このメタデータは「バニシング」のバグか機能ですか?回避策はありますか?

#include "zmqpp/zmqpp.hpp" 
#include "zmqpp/curve.hpp" 

int main() 
{ 
    zmqpp::curve::keypair client_keypair = zmqpp::curve::generate_keypair(); 
    zmqpp::curve::keypair server_keypair = zmqpp::curve::generate_keypair(); 

    std::cout << "Client Public Key: " << client_keypair.public_key << std::endl; 
    std::cout << "Server Public Key: " << server_keypair.public_key << std::endl; 

    zmqpp::context context; 

    zmqpp::auth authenticator(context); 
    authenticator.set_verbose(false); 
    authenticator.configure_curve(client_keypair.public_key); 

    zmqpp::socket curve_rep(context, zmqpp::socket_type::rep); 
    curve_rep.set(zmqpp::socket_option::curve_server, true); 
    curve_rep.set(zmqpp::socket_option::curve_secret_key, server_keypair.secret_key); 
    curve_rep.bind("tcp://127.0.0.1:4242"); 

    zmqpp::socket curve_req(context, zmqpp::socket_type::req); 
    curve_req.set(zmqpp::socket_option::curve_server_key, server_keypair.public_key); 
    curve_req.set(zmqpp::socket_option::curve_public_key, client_keypair.public_key); 
    curve_req.set(zmqpp::socket_option::curve_secret_key, client_keypair.secret_key); 
    curve_req.connect("tcp://127.0.0.1:4242"); 

    zmqpp::socket internal_rep(context, zmqpp::socket_type::rep); 
    internal_rep.bind("inproc://clear"); 

    zmqpp::socket internal_req(context, zmqpp::socket_type::req); 
    internal_req.connect("inproc://clear"); 

    { 
     zmqpp::message msg; 
     msg << "Hello"; 
     curve_req.send(msg); 
    } 

    { 
     zmqpp::message msg; 
     curve_rep.receive(msg); 

     // read User-Id 
     std::string user_id; 
     std::cout << "- Before forward: "; 
     if (msg.get_property("User-Id", user_id)) 
      std::cout << user_id << std::endl; 
     else 
      std::cout << "No user id" << std::endl; 

     // Forward message 
     internal_req.send(msg); 
    } 

    { 
     zmqpp::message msg; 
     internal_rep.receive(msg); 

     // read User-Id 
     std::string user_id; 
     std::cout << "- After forward: "; 
     if (msg.get_property("User-Id", user_id)) 
      std::cout << user_id << std::endl; 
     else 
      std::cout << "No user id" << std::endl; 

     std::string content; 
     msg >> content; 

     std::cout << "- Message: " << content << std::endl; 
    } 

    { 
     zmqpp::message msg; 
     msg << "world !"; 
     internal_rep.send(msg); 
    } 

    { 
     zmqpp::message msg; 
     internal_req.receive(msg); 
     // Forward message 
     curve_rep.send(msg); 
    } 

    { 
     zmqpp::message msg; 
     curve_req.receive(msg); 
     std::cout << "- Message: " << msg.get<std::string>(0) << std::endl; 
    } 

    return 0; 
} 

出力:

Client Public Key: }-}3(fH/r!I/9*tJX0bN/TT]Y2Qd#{IqszYzBX.g 
Server Public Key: [email protected]@e3jW)[email protected]?y9mD(QWd8 
auth: Starting ZAP Authentication Server 
- Before forward: }-}3(fH/r!I/9*tJX0bN/TT]Y2Qd#{IqszYzBX.g 
- After forward: No user id 
- Message: Hello 
- Message: world ! 
auth: Shutdown ZAP Authentication Server 

答えて

4

これはZMQの混乱要素とすることができます。あなたが参照しているメタデータは、ZMQメッセージ自体の一部ではなく、そのメッセージを受け取った接続の一部です。あなたがそのメッセージのプロパティとしてアクセスできるという事実は、受信ソケットがそのメッセージを適切に処理する必要があるすべての情報を使って、あるソケットから別のソケットにデータがどのように転送されるかというZMQ有線プロトコルの成果物です。 ZMQメッセージには「ヘッダ」自体はなく、単に「フレーム」を持ち、ZMQソケットはメタデータを含むときにそれらのフレームをどのように処理するかを知っています。

これは、Curve暗号をネゴシエートする詳細が与えられているソケットは、メッセージと受信ソケットと共に暗号メタデータを送信し、暗号の詳細が設定され、そのメタデータで何をすべきかを知っている。暗号を持たない「通常の」ソケットで送信すると、そのメタデータは削除されます。バックエンドのソケットのペアが暗号を使用すると、フロントエンドに適用されたメタデータをもはや持たず、ブローカのバックエンドソケットに適用されたユーザIDを持ちます。

メタデータをメッセージに追加してバックエンドに送り返す場合は、直接または新しいメッセージフレーム(マルチパートメッセージ)にメッセージデータに追加する必要があります。自分でそれを処理すれば、それはもはやメタデータではなくなり、これはファーストクラスのデータになります。

関連する問題