TlsContext.h revision 8d51ab70
18d51ab70SShuo Chen#pragma once
28d51ab70SShuo Chen
38d51ab70SShuo Chen#include "Common.h"
48d51ab70SShuo Chen#include "TlsConfig.h"
58d51ab70SShuo Chen
68d51ab70SShuo Chen// Internal class
78d51ab70SShuo Chenclass TlsContext : noncopyable
88d51ab70SShuo Chen{
98d51ab70SShuo Chen public:
108d51ab70SShuo Chen  enum Endpoint { kClient, kServer };
118d51ab70SShuo Chen
128d51ab70SShuo Chen  TlsContext(Endpoint type, TlsConfig* config)
138d51ab70SShuo Chen    : context_(type == kServer ? tls_server() : tls_client())
148d51ab70SShuo Chen  {
158d51ab70SShuo Chen    check(tls_configure(context_, config->get()));
168d51ab70SShuo Chen  }
178d51ab70SShuo Chen
188d51ab70SShuo Chen  // TlsContext() : context_(NULL) {}
198d51ab70SShuo Chen
208d51ab70SShuo Chen  TlsContext(TlsContext&& rhs)
218d51ab70SShuo Chen  {
228d51ab70SShuo Chen    swap(rhs);
238d51ab70SShuo Chen  }
248d51ab70SShuo Chen
258d51ab70SShuo Chen  ~TlsContext()
268d51ab70SShuo Chen  {
278d51ab70SShuo Chen    tls_free(context_);
288d51ab70SShuo Chen  }
298d51ab70SShuo Chen
308d51ab70SShuo Chen  TlsContext& operator=(TlsContext rhs)  // ???
318d51ab70SShuo Chen  {
328d51ab70SShuo Chen    swap(rhs);
338d51ab70SShuo Chen    return *this;
348d51ab70SShuo Chen  }
358d51ab70SShuo Chen
368d51ab70SShuo Chen  void swap(TlsContext& rhs)
378d51ab70SShuo Chen  {
388d51ab70SShuo Chen    std::swap(context_, rhs.context_);
398d51ab70SShuo Chen  }
408d51ab70SShuo Chen
418d51ab70SShuo Chen  void reset(struct tls* ctx) { context_ = ctx; }
428d51ab70SShuo Chen
438d51ab70SShuo Chen  struct tls* get() { return context_; }
448d51ab70SShuo Chen
458d51ab70SShuo Chen  // if there is no error, this will segfault.
468d51ab70SShuo Chen  const char* error() { return tls_error(context_); }
478d51ab70SShuo Chen
488d51ab70SShuo Chen  int connect(const char* hostport, const char* servername = nullptr)
498d51ab70SShuo Chen  {
508d51ab70SShuo Chen    return tls_connect_servername(context_, hostport, nullptr, servername);
518d51ab70SShuo Chen  }
528d51ab70SShuo Chen
538d51ab70SShuo Chen  int handshake()
548d51ab70SShuo Chen  {
558d51ab70SShuo Chen    int ret = -1;
568d51ab70SShuo Chen    do {
578d51ab70SShuo Chen      ret = tls_handshake(context_);
588d51ab70SShuo Chen    } while(ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT);
598d51ab70SShuo Chen    return ret;
608d51ab70SShuo Chen  }
618d51ab70SShuo Chen
628d51ab70SShuo Chen  // void accept(
638d51ab70SShuo Chen private:
648d51ab70SShuo Chen  void check(int ret)
658d51ab70SShuo Chen  {
668d51ab70SShuo Chen    if (ret != 0)
678d51ab70SShuo Chen    {
688d51ab70SShuo Chen      LOG_FATAL << tls_error(context_);
698d51ab70SShuo Chen    }
708d51ab70SShuo Chen  }
718d51ab70SShuo Chen
728d51ab70SShuo Chen  struct tls* context_ = nullptr;
738d51ab70SShuo Chen};
74