CLX C++ Libraries
Home >> sockmanager >> ssl::sockmanager

Declarations

namespace ssl {
    typedef basic_sockmanager<SOCK_STREAM, AF_INET, 0> sockmanager;
};

Overview

ssl::sockmanager は,SSL 通信用の sockmanager です. その他の sockmanager と同様のインターフェースで使用することができます.

Examples

example_sslmanager_send.cpp

#include <cstdio>
#include <iostream>
#include <string>
#include "clx/ssl.h"

/* ------------------------------------------------------------------------- */
//  send_msg
/* ------------------------------------------------------------------------- */
bool send_msg(clx::ssl::rawsocket* s, clx::ssl::sockmanager& sm) {
    // read string from std::cin
    std::string buf;
    if (!std::getline(std::cin, buf)) {
        sm.stop();
        return false;
    }
    
    // write string to the socket
    for (clx::ssl::sockmanager::iterator pos = sm.begin(); pos != sm.end(); pos++) {
        if (sm.socket(pos)->socket() == s->socket()) continue;
        clx::ssl::sockstream* ss = dynamic_cast<clx::ssl::sockstream*>(sm.socket(pos));
        *ss << buf << std::endl;
    }
    return true;
}

/* ------------------------------------------------------------------------- */
//  recv_msg
/* ------------------------------------------------------------------------- */
bool recv_msg(clx::ssl::rawsocket* s, clx::ssl::sockmanager& sm) {
    clx::ssl::sockstream* ss = dynamic_cast<clx::ssl::sockstream*>(s);
    
    std::string buf;
    if (!std::getline(*ss, buf)) {
        ss->close();
        return false;
    }
    std::cout << buf << std::endl;
    return true;
}

/* ------------------------------------------------------------------------- */
//  main
/* ------------------------------------------------------------------------- */
int main(int argc, char* argv[])
{
    if (argc < 2) {
        std::cerr << "usage: " << argv[0] << " host" << std::endl;
        return -1;
    }
    
    try {
        clx::ssl::sockmanager sm;
        int port = clx::ssl::port(argv[2]);
        sm.add(new clx::ssl::sockstream(argv[1], port), recv_msg);
        sm.add(new clx::ssl::rawsocket(0), send_msg); // for std::cin
        sm.start();
    }
    catch (clx::socket_error& e) {
        std::cerr << e.what() << std::endl;
        std::exit(-1);
    }
    catch (clx::sockaddress_error& e) {
        std::cerr << e.what() << std::endl;
        std::exit(-1);
    }
    catch (std::runtime_error& e) {
        std::cerr << e.what() << std::endl;
        std::exit(-1);
    }
    
    return 0;
}

example_sslmanager_send.cpp

#include <iostream>
#include <cstring>
#include "clx/ssl.h"

/* ----------------------------------------------------------------- */
//  accept_handler
/* ----------------------------------------------------------------- */
template <class Socket, class Service>
class accept_handler {
public:
    typedef Socket socket_type;
    typedef clx::ssl::acceptor acceptor_type;
    typedef Service service_handler;
    
    explicit accept_handler(const std::string& pub, const std::string& priv) :
        public_(pub), private_(priv) {}
    
    explicit accept_handler(const char* pub, const char* priv) :
        public_(pub), private_(priv) {}
    
    virtual ~accept_handler() throw() {}
    
    template <class T, class SockManager>
    bool operator()(T* s, SockManager& sm) {
        acceptor_type* server = dynamic_cast<acceptor_type*>(s);
        socket_type* client = new socket_type(server->accept(public_, private_));
        if (client == NULL) throw std::bad_alloc();
        
        sm.add(client, service_handler(server->socket()));
        return true;
    }
    
private:
    std::string public_;
    std::string private_;
};

/* ------------------------------------------------------------------------- */
//  chat_service
/* ------------------------------------------------------------------------- */
class chat_service {
public:
    typedef clx::ssl::sockstream socket_type;
    
    chat_service(socket_int s) : accid_(s) {}
    
    template <class SockT, class SockManager>
    bool operator()(SockT* s, SockManager& sm) {
        socket_type* ss = dynamic_cast<socket_type*>(s);
        
        std::string ipaddr = ss->address().ipaddr();
        int port = ss->address().port();
        std::string buf;
        if (!std::getline(*ss, buf)) {
            std::cout << ipaddr << ':' << port << ": connection was closed" << std::endl;
            ss->close();
            return false;
        }
        
        /*
         * 接続されている全クライアントに受信したメッセージを
         * message (xxx.xxx.xxx.xxx:port)
         * という形で送信する.ただし,sockmanager には接続確立用の
         * ソケットも登録されてあるため,そのソケットには送らないように
         * 注意する.コンストラクタで接続確立用のソケットのソケット番号
         * を知らせてもらっている (accid_) ので,その値を基に判断する.
         */
        buf += " (" + ipaddr + ":" + clx::lexical_cast<std::string>(port) + ")";
        for (typename SockManager::iterator pos = sm.begin(); pos != sm.end(); pos++) {
            if (sm.socket(pos)->socket() == accid_) continue;
            socket_type* os = dynamic_cast<socket_type*>(sm.socket(pos));
            *os << buf << std::endl;
        }
        
        return true;
    }
    
private:
    socket_int accid_; // acceptorのソケット番号
};

/* ------------------------------------------------------------------------- */
//  main
/* ------------------------------------------------------------------------- */
int main(int argc, char* argv[]) {
    typedef accept_handler<clx::ssl::sockstream, chat_service> handler_type;
    
    try {
        clx::ssl::sockmanager s;
        int port = clx::ssl::port(argv[1]);
        s.add(new clx::ssl::acceptor(port), handler_type("public.key", "private.key"));
        s.start();
    }
    catch (clx::socket_error& e) {
        std::cerr << e.what() << std::endl;
        std::exit(-1);
    }
    catch (clx::sockaddress_error& e) {
        std::cerr << e.what() << std::endl;
        std::exit(-1);
    }
    catch (std::runtime_error& e) {
        std::cerr << e.what() << std::endl;
        std::exit(-1);
    }
    
    return 0;
}

Related Pages

  1. CLX C++ Libraries - sockmanager
  2. CLX C++ Libraries - ssl::socket
  3. CLX C++ Libraries - ssl::acceptor

References

  1. OpenSSL: The Open Source toolkit for SSL/TLS
  2. OpenSSL 日本語サイト: The Open Source toolkit for SSL/TLS
  3. Life like a clown - Hello, OpenSSL!
  4. Life like a clown - OpenSSL と select