Пример #1
0
static void
s_hup_handler(int sig) {
  (void)sig;

  if (lagopus_log_get_destination() == LAGOPUS_LOG_EMIT_TO_FILE) {
    lagopus_msg_info("The log file turned over.\n");
    (void)lagopus_log_reinitialize();
    lagopus_msg_info("The log file turned over.\n");
  }
}
Пример #2
0
lagopus_result_t
port_config(struct bridge *bridge,
            struct ofp_port_mod *port_mod,
            struct ofp_error *error) {
  struct port *port;
  struct ofp_port *ofp_port;
  uint32_t oldconfig, newconfig;

  if (port_mod->port_no != OFPP_CONTROLLER) {
    port = port_lookup(&bridge->ports, port_mod->port_no);
    if (port == NULL) {
      error->type = OFPET_PORT_MOD_FAILED;
      error->code = OFPPMFC_BAD_PORT;
      lagopus_msg_info("port config: %d: no such port (%d:%d)\n",
                       port_mod->port_no, error->type, error->code);
      return LAGOPUS_RESULT_OFP_ERROR;
    }
    ofp_port = &port->ofp_port;
    if (port->interface == NULL) {
      error->type = OFPET_PORT_MOD_FAILED;
      error->code = OFPPMFC_BAD_HW_ADDR;
      lagopus_msg_info("port config: %d: do not assigned interface (%d:%d)\n",
                       port_mod->port_no, error->type, error->code);
      return LAGOPUS_RESULT_OFP_ERROR;
    }
  } else {
    port = NULL; /* XXX shut out warning */
    ofp_port = &bridge->controller_port;
  }
  /* XXX write lock for thread safe */
  if ((port_mod->config & (uint32_t)~port_mod->mask) != 0) {
    error->type = OFPET_PORT_MOD_FAILED;
    error->code = OFPPMFC_BAD_CONFIG;
    lagopus_msg_info("port config: "
                     "config(0x%x) and mask(0x%x) inconsistency (%d:%d)\n",
                     port_mod->config, port_mod->mask,
                     error->type, error->code);
    return LAGOPUS_RESULT_OFP_ERROR;
  }
  oldconfig = ofp_port->config;
  newconfig = oldconfig;
  newconfig &= (uint32_t)~port_mod->mask;
  newconfig |= port_mod->config;
  ofp_port->config = newconfig;
  /* advertise, depend on lower driver */
  if ((oldconfig != newconfig ||
       ofp_port->advertised != port_mod->advertise) &&
      port_mod->port_no != OFPP_CONTROLLER) {
    ofp_port->advertised = port_mod->advertise;
    lagopus_change_physical_port(port);
  }
  /* XXX unlock */

  return LAGOPUS_RESULT_OK;
}
Пример #3
0
/* Add a new bridge. */
lagopus_result_t
bridge_add(struct bridge_list *bridge_list, const char *name, uint64_t dpid) {
  struct bridge *bridge;

  /* Find bridge. */
  bridge = bridge_lookup(bridge_list, name);
  if (bridge != NULL) {
    return LAGOPUS_RESULT_ALREADY_EXISTS;
  }

  /* Allocate a new bridge. */
  bridge = bridge_alloc(name);
  if (bridge == NULL) {
    return LAGOPUS_RESULT_NO_MEMORY;
  }

  /* If given dpid is zero, generate random dpid value. */
  if (dpid == 0) {
    dpid = bridge_dpid_generate();
  }
  bridge->dpid = dpid;

  flowdb_wrlock(NULL);
  TAILQ_INSERT_TAIL(bridge_list, bridge, entry);
  flowdb_wrunlock(NULL);

  lagopus_msg_info("Bridge %s dpid:%0" PRIx64 " is added\n", name, dpid);
  return LAGOPUS_RESULT_OK;
}
Пример #4
0
lagopus_result_t
snmpmgr_start(void) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  (void)lagopus_mutex_lock(&snmp_state_lock);
  if (state == SNMPMGR_RUNNABLE) {
    if (is_thread == false) {
      state = SNMPMGR_RUNNING;
      (void)lagopus_mutex_unlock(&snmp_state_lock);
      /* open the session to AgentX master agent here. */
      init_snmp(SNMP_TYPE);
      /* send_*_trap always return SNMP_ERR_NOERROR */
      (void)send_coldStart_trap();
      ret = LAGOPUS_RESULT_OK;
      lagopus_msg_info("SNMP manager started.\n");
    } else {
      /* Note:
       * If is_thread is true, init_snmp and send_coldStart_trap
       * are called inside snmpmgr_thread_loop
       */
      (void)lagopus_mutex_unlock(&snmp_state_lock);
      ret = lagopus_thread_start(&snmpmgr, false);
    }
  } else {
    (void)lagopus_mutex_unlock(&snmp_state_lock);
    ret = LAGOPUS_RESULT_NOT_STARTED;
  }
  return ret;
}
Пример #5
0
static inline void
s_shutdown(shutdown_grace_level_t level) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;

  if ((ret = global_state_request_shutdown(level)) ==
      LAGOPUS_RESULT_OK) {
    lagopus_msg_info("The shutdown request accepted.\n");
  } else {
    lagopus_perror(ret);
    lagopus_msg_error("Can't request shutdown.\n");
  }
}
Пример #6
0
static lagopus_result_t
snmpmgr_thread_loop(const lagopus_thread_t *selfptr, void *arg) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  lagopus_chrono_t interval = DEFAULT_SNMPMGR_LOOP_INTERVAL_NSEC;
  global_state_t global_state;
  shutdown_grace_level_t l;
  (void)selfptr;
  (void)arg;

  /* open the session to AgentX master agent here. */
  init_snmp(SNMP_TYPE);

  /* wait all modules start */
  if ((ret = global_state_wait_for(GLOBAL_STATE_STARTED,
                                   &global_state, &l,
                                   -1 /* forever! */)) !=
      LAGOPUS_RESULT_OK) {
    lagopus_perror(ret);
  } else {
    if (global_state != GLOBAL_STATE_STARTED) {
      lagopus_exit_fatal("must not happen. die!\n");
    }
  }

  /* all modules have started, then send a coldStart trap */
  (void)send_coldStart_trap();

  lagopus_msg_info("SNMP manager started (as a thread).\n");

  /* main loop */
  while (keep_running) {
    (void)lagopus_mutex_lock(&snmp_lock);
    ret = internal_snmpmgr_poll(interval);
    (void)lagopus_mutex_unlock(&snmp_lock);
    if (ret != LAGOPUS_RESULT_OK && ret != LAGOPUS_RESULT_TIMEDOUT) {
      lagopus_msg_warning("failed to poll SNMP AgentX request: %s",
                          lagopus_error_get_string(ret));
    }
    check_status_and_send_traps();
  }

  /* stop SNMP */
  snmp_shutdown(SNMP_TYPE);

  (void)lagopus_mutex_lock(&snmp_state_lock);
  if (state != SNMPMGR_RUNNABLE) {
    state = SNMPMGR_NONE;
  }
  (void)lagopus_mutex_unlock(&snmp_state_lock);

  return LAGOPUS_RESULT_OK;
}
Пример #7
0
static void
app_lcore_io_tx_cleanup(struct app_lcore_params_io *lp) {
  unsigned i;

  for (i = 0; i < lp->tx.n_nic_ports; i ++) {
    uint8_t portid = lp->tx.nic_ports[i];

    /* Flush TX and RX queues. */
    lagopus_msg_info("Cleanup physical port %u\n", portid);
    rte_eth_dev_stop(portid);
    rte_eth_dev_close(portid);
  }
}
Пример #8
0
lagopus_result_t
load_conf_initialize(int argc, const char *const argv[],
                     void *extarg, lagopus_thread_t **retptr) {
  (void) argc;
  (void) argv;
  (void) extarg;
  (void) retptr;

  lagopus_msg_info("load_conf_initiaize.\n");
  pthread_once(&initialized, initialize_internal);

  return LAGOPUS_RESULT_OK;
}
Пример #9
0
static void
s_term_handler(int sig) {
  lagopus_result_t r = LAGOPUS_RESULT_ANY_FAILURES;
  global_state_t gs = GLOBAL_STATE_UNKNOWN;

  if ((r = global_state_get(&gs)) == LAGOPUS_RESULT_OK) {

    if ((int)gs == (int)GLOBAL_STATE_STARTED) {

      shutdown_grace_level_t l = SHUTDOWN_UNKNOWN;
      if (sig == SIGTERM || sig == SIGINT) {
        l = SHUTDOWN_GRACEFULLY;
      } else if (sig == SIGQUIT) {
        l = SHUTDOWN_RIGHT_NOW;
      }
      if (IS_VALID_SHUTDOWN(l) == true) {
        lagopus_msg_info("About to request shutdown(%s)...\n",
                         (l == SHUTDOWN_RIGHT_NOW) ?
                         "RIGHT_NOW" : "GRACEFULLY");
        if ((r = global_state_request_shutdown(l)) == LAGOPUS_RESULT_OK) {
          lagopus_msg_info("The shutdown request accepted.\n");
        } else {
          lagopus_perror(r);
          lagopus_msg_error("can't request shutdown.\n");
        }
      }

    } else if ((int)gs < (int)GLOBAL_STATE_STARTED) {
      if (sig == SIGTERM || sig == SIGINT || sig == SIGQUIT) {
        s_got_term_sig = true;
      }
    } else {
      lagopus_msg_debug(5, "The system is already shutting down.\n");
    }
  }

}
Пример #10
0
static int
check_cert_chain(const SSL *ssl) {
  int ret = -1;
  char *issuer = NULL, *subject = NULL;
  X509 *peer = NULL;

  if (SSL_get_verify_result(ssl) != X509_V_OK) {
    lagopus_msg_warning("SSL_get_verify_result() failed.\n");
    return -1;
  }

  peer = SSL_get_peer_certificate(ssl);
  if (peer == NULL) {
    lagopus_msg_warning("SSL_get_peer_certificate() failed.\n");
    return -1;
  }

  issuer = X509_NAME_oneline(X509_get_issuer_name(peer), NULL, 0);
  if (issuer == NULL) {
    lagopus_msg_warning("no memory, get_issuer_name failed.\n");
    ret = -1;
    goto done;
  }

  subject = X509_NAME_oneline(X509_get_subject_name(peer), NULL, 0);
  if (issuer == NULL) {
    lagopus_msg_warning("no memory, get_subject_name failed.\n");
    ret = -1;
    goto done;
  }

  if (check_certificates != NULL) {
    if (check_certificates(issuer, subject) == LAGOPUS_RESULT_OK) {
      ret = 0;
    } else {
      ret = -1;
    }
    lagopus_msg_info("issuer:[%s], subject:[%s] ret: %d\n", issuer, subject, ret);
  } else {
    lagopus_msg_warning("check_certificates function is null.\n");
  }

done:
  free(issuer);
  free(subject);
  X509_free(peer);

  return ret;
}
Пример #11
0
lagopus_result_t
dp_thread_shutdown(lagopus_thread_t *threadptr,
                   lagopus_mutex_t *lockptr,
                   bool *runptr,
                   shutdown_grace_level_t level) {
  bool is_valid = false;
  lagopus_chrono_t nsec;
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;

  lagopus_msg_info("shutdown called\n");
  lagopus_mutex_lock(lockptr);
  if (*runptr == false) {
    goto done;
  }

  ret = lagopus_thread_is_valid(threadptr, &is_valid);
  if (ret != LAGOPUS_RESULT_OK || is_valid == false) {
    lagopus_perror(ret);
    goto done;
  }

  /* XXX UP TO main() */
  switch (level) {
    case SHUTDOWN_RIGHT_NOW:
      nsec = TIMEOUT_SHUTDOWN_RIGHT_NOW;
      break;
    case SHUTDOWN_GRACEFULLY:
      nsec = TIMEOUT_SHUTDOWN_GRACEFULLY;
      break;
    default:
      lagopus_msg_fatal("unknown shutdown level %d\n", level);
      ret = LAGOPUS_RESULT_ANY_FAILURES;
      goto done;
  }

  *runptr = false;
  ret = lagopus_thread_wait(threadptr, nsec);
  if (ret != LAGOPUS_RESULT_OK) {
    lagopus_perror(ret);
    goto done;
  }

done:
  lagopus_mutex_unlock(lockptr);
  return ret;
}
Пример #12
0
void
dp_finalproc(const lagopus_thread_t *t, bool is_canceled, void *arg) {
  bool is_valid = false;
  struct dataplane_arg *dparg;
  lagopus_result_t ret;

  (void) is_canceled;
  dparg = arg;

  lagopus_msg_info("finalproc in %p\n", *dparg->threadptr);
  if (*t != *dparg->threadptr) {
    lagopus_exit_fatal("other threads worked t:%p, my_thread:%p\n",
                       *t, *dparg->threadptr);
  }

  ret = lagopus_thread_is_valid(dparg->threadptr, &is_valid);
  if (ret != LAGOPUS_RESULT_OK || is_valid == false) {
    lagopus_perror(ret);
    return;
  }
}
Пример #13
0
static lagopus_result_t
ofp_role_write(struct channel *channel, void *val) {
  struct role_write_vars *v = val;

  if (channel_is_alive(channel) == true) {
    /* packet filtering. */
    if (channel_role_channel_check_mask(channel, v->type, v->reason) == true) {
      v->ret = ofp_write_channel(channel, v->pbuf);
    } else {
      /* Not send packet. */
      v->ret = LAGOPUS_RESULT_OK;
    }
  } else {
    lagopus_msg_info("Channel is not alive, drop asynchronous message(%s)\n",
                     ofp_type_str(v->type));
    /* Not send packet. */
    v->ret = LAGOPUS_RESULT_OK;
  }

  return LAGOPUS_RESULT_OK;
}
Пример #14
0
static SSL_CTX *get_ssl_ctx(char *ca_dir, char *cert, char *key) {
  SSL_CTX *ssl_ctx;
  const SSL_METHOD *method;

  lagopus_msg_info("ca_dir:[%s], cert:[%s], key:[%s]\n", ca_dir, cert, key);
  method = TLSv1_method();
  ssl_ctx = SSL_CTX_new(method);
  if (ssl_ctx == NULL) {
    lagopus_msg_warning("no memory.\n");
    return NULL;
  }

  /* add client cert. */
  if (SSL_CTX_use_certificate_file(ssl_ctx, cert, SSL_FILETYPE_PEM) != 1) {
    lagopus_msg_warning("SSL_CTX_use_certificate_file(%s) fail.\n", cert);
    SSL_CTX_free(ssl_ctx);
    return NULL;
  }

  /* add client private key. */
  if (SSL_CTX_use_PrivateKey_file(ssl_ctx, key, SSL_FILETYPE_PEM) != 1) {
    lagopus_msg_warning("SSL_CTX_use_PrivateKey_file(%s) fail.\n", key);
    SSL_CTX_free(ssl_ctx);
    return NULL;
  }

  /* loading ca cert */
  if (SSL_CTX_load_verify_locations(ssl_ctx, NULL, ca_dir) != 1) {
    lagopus_msg_warning("SSL_CTX_load_verify_locations(%s) fail.\n", ca_dir);
    SSL_CTX_free(ssl_ctx);
    return NULL;
  }

  SSL_CTX_set_verify_depth(ssl_ctx, 1);/* XXX depth is configurable? */
  SSL_CTX_set_verify(ssl_ctx,
                     SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback);

  return ssl_ctx;
}
Пример #15
0
lagopus_result_t
lagopus_get_port_statistics(lagopus_hashmap_t *hm,
                            struct ofp_port_stats_request *request,
                            struct port_stats_list *list,
                            struct ofp_error *error) {
  struct port *port;

  if (request->port_no == OFPP_ANY) {
    lagopus_hashmap_iterate(hm, port_do_stats_iterate, list);
  } else {
    if (lagopus_hashmap_find(hm, (void *)request->port_no, &port)
        != LAGOPUS_RESULT_OK) {
      error->type = OFPET_BAD_REQUEST;
      error->code = OFPBRC_BAD_PORT;
      lagopus_msg_info("port stats: %d: no such port (%d:%d)\n",
                       request->port_no, error->type, error->code);
      return LAGOPUS_RESULT_OFP_ERROR;
    }
    port_add_stats(port, list);
  }

  return LAGOPUS_RESULT_OK;
}
Пример #16
0
void
dp_freeproc(const lagopus_thread_t *t, void *arg) {
  bool is_valid = false;
  struct dataplane_arg *dparg;
  lagopus_result_t ret;

  dparg = arg;

  lagopus_msg_info("freeproc in\n");
  if (*t != *dparg->threadptr) {
    lagopus_exit_fatal("other threads worked %p, %p", *t, *dparg->threadptr);
  }

  ret = lagopus_thread_is_valid(dparg->threadptr, &is_valid);
  if (ret != LAGOPUS_RESULT_OK || is_valid == false) {
    lagopus_perror(ret);
    return;
  }
  /* ADD delete ports? */

  lagopus_mutex_destroy(dparg->lock);
  *dparg->lock = NULL;
}
Пример #17
0
lagopus_result_t
ofp_role_channel_write(struct pbuf *pbuf, uint64_t dpid,
                       uint8_t type, uint8_t reason) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;

  if (pbuf != NULL) {
    struct role_write_vars v;

    v.type = type;
    v.reason = reason;
    v.pbuf = pbuf;
    v.ret = LAGOPUS_RESULT_ANY_FAILURES;

    ret = channel_mgr_dpid_iterate(dpid, ofp_role_write, (void *) &v);

    if (ret != LAGOPUS_RESULT_OK) {
      if (ret == LAGOPUS_RESULT_NOT_OPERATIONAL ||
          ret == LAGOPUS_RESULT_NOT_FOUND) {
        lagopus_msg_info("Channel is not alive, drop asynchronous message(%s)\n",
                         ofp_type_str(v.type));
        /* Not send packet. */
        ret = LAGOPUS_RESULT_OK;
      } else {
        ret = v.ret;
      }
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  if (ret == LAGOPUS_RESULT_OK && pbuf != NULL) {
    /* move getp to putp. */
    pbuf_getp_set(pbuf, pbuf_putp_get(pbuf));
  }

  return ret;
}
Пример #18
0
static void
initialize_internal(void) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  void *logger_client_arg = NULL;
  char *master_agentx_socket = NULL;
  char *ping_interval_string = NULL;
  uint16_t ping_interval = 0;

  state = SNMPMGR_NONE;

  /* `is_thread` is able to be changed only once here */
  is_thread = is_thread_dummy;
  if (is_thread == false && thdptr_dummy != NULL) {
    *thdptr_dummy = NULL;
  } else if (thdptr_dummy != NULL) {
    *thdptr_dummy = &snmpmgr;
  } else {
    /* never reached! */
    return;
  }

  if (lagopus_mutex_create(&snmp_lock) != LAGOPUS_RESULT_OK) {
    return;
  }

  if (lagopus_mutex_create(&snmp_state_lock) != LAGOPUS_RESULT_OK) {
    return;
  }

  snmp_set_do_debugging(false);

  /* setup Net-SNMP logger to use the lagopus logging function */
  if (snmp_register_callback(SNMP_CALLBACK_LIBRARY,
                             SNMP_CALLBACK_LOGGING,
                             snmp_log_callback_wrapper,
                             logger_client_arg) != SNMPERR_SUCCESS) {
    return;
  }
  snmp_enable_calllog();

  /* setup the SNMP module to be Agentx subagent */
  netsnmp_enable_subagent();

#ifdef THE_CONFSYS_ERA
  master_agentx_socket = config_get("snmp master-agentx-socket WORD");
  if (master_agentx_socket == NULL) {
    config_set_default("snmp master-agentx-socket WORD",
                       (char *)DEFAULT_SNMPMGR_AGENTX_SOCKET);
    master_agentx_socket = config_get("snmp master-agentx-socket WORD");
  }
#else
  /*
   * FIXME:
   *	Fetch it from the datastore.
   */
  master_agentx_socket = (char *)DEFAULT_SNMPMGR_AGENTX_SOCKET;
#endif /* THE_CONFSYS_ERA */
  lagopus_msg_debug(25, "master agentx socket is %s\n", master_agentx_socket);

  if (netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                            NETSNMP_DS_AGENT_X_SOCKET,
                            master_agentx_socket)
      != SNMPERR_SUCCESS) {
    initialize_ret = LAGOPUS_RESULT_SNMP_API_ERROR;
    return;
  }

  /* don't read/write configuration files */
  if (netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
                             NETSNMP_DS_LIB_DONT_PERSIST_STATE,
                             true) != SNMPERR_SUCCESS) {
    initialize_ret = LAGOPUS_RESULT_SNMP_API_ERROR;
    return;
  }
  if (netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
                             NETSNMP_DS_LIB_DISABLE_PERSISTENT_LOAD,
                             true) != SNMPERR_SUCCESS) {
    initialize_ret = LAGOPUS_RESULT_SNMP_API_ERROR;
    return;
  }

  /* the interval [sec] to send ping to AgentX master agent */
#ifdef THE_CONFSYS_ERA
  ping_interval_string = config_get("snmp ping-interval-second 1-255");
  if (ping_interval_string != NULL &&
      (ret = check_ping_interval(ping_interval_string, &ping_interval))
      != LAGOPUS_RESULT_OK) {
    config_set_default("snmp ping-interval-second 1-255",
                       (char *) __STR__(DEFAULT_SNMPMGR_AGENTX_PING_INTERVAL_SEC));
    ping_interval_string = config_get("snmp ping-interval-second 1-255");
    ping_interval = DEFAULT_SNMPMGR_AGENTX_PING_INTERVAL_SEC; /* default value */
  }
#else
  /*
   * FIXME:
   *	Fetch it from the datastore.
   */
  ping_interval = DEFAULT_SNMPMGR_AGENTX_PING_INTERVAL_SEC;
#endif /* THE_CONFSYS_ERA */

  if (netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                         NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL,
                         (int)ping_interval)
      != SNMPERR_SUCCESS) {
    initialize_ret = LAGOPUS_RESULT_SNMP_API_ERROR;
    return;
  }

  if (init_agent(SNMP_TYPE) != SNMPERR_SUCCESS) {
    initialize_ret = LAGOPUS_RESULT_SNMP_API_ERROR;
    return;
  }

  if ((ret = lagopus_hashmap_create(&iftable_entry_hash,
                                    LAGOPUS_HASHMAP_TYPE_STRING,
                                    delete_entry)) != LAGOPUS_RESULT_OK) {
    lagopus_perror(ret);
    exit(1);
  }

  init_ifTable();
  init_ifNumber();
  init_dot1dBaseBridgeAddress();
  init_dot1dBaseNumPorts();
  init_dot1dBasePortTable();
  init_dot1dBaseType();

  if (is_thread == false) {
    initialize_ret = LAGOPUS_RESULT_OK;
  } else {
    keep_running = true;
    initialize_ret = lagopus_thread_create(&snmpmgr,
                                           snmpmgr_thread_loop,
                                           snmpmgr_thread_finally_called,
                                           NULL,
                                           "snmpmgr",
                                           NULL);
  }

  lagopus_msg_info("SNMP manager initialized.\n");
}
Пример #19
0
static lagopus_result_t
connect_tls(struct session *s, const char *host, const char *port) {
  int ret;
  BIO *sbio;

  (void) host;
  (void) port;

  lagopus_msg_info("tls handshake start.\n");

  if (IS_TLS_NOT_INIT(s)) {
    SSL_CTX *ssl_ctx;

    ssl_ctx = get_ssl_ctx(GET_TLS_CTX(s)->ca_dir, GET_TLS_CTX(s)->cert,
                          GET_TLS_CTX(s)->key);
    if (ssl_ctx == NULL) {
      lagopus_msg_warning("get_ssl_ctx() fail.\n");
      return LAGOPUS_RESULT_TLS_CONN_ERROR;
    }
    GET_TLS_CTX(s)->ctx = ssl_ctx;
  }

  if (GET_TLS_CTX(s)->ssl == NULL) {
    SSL *ssl;
    ssl = SSL_new(GET_TLS_CTX(s)->ctx);
    if (ssl == NULL) {
      lagopus_msg_warning("no memory.\n");
      return LAGOPUS_RESULT_TLS_CONN_ERROR;
    }
    GET_TLS_CTX(s)->ssl = ssl;
  }

  if (SSL_get_rbio(GET_TLS_CTX(s)->ssl) == NULL) {
    sbio = BIO_new_socket(s->sock, BIO_NOCLOSE);
    SSL_set_bio(GET_TLS_CTX(s)->ssl, sbio, sbio);
  }

  ret = SSL_connect(GET_TLS_CTX(s)->ssl);
  if (ret == 0) {
    lagopus_msg_warning("tls handshake failed.\n");
    return LAGOPUS_RESULT_TLS_CONN_ERROR;
  } else if (ret < 0
             && (SSL_get_error(GET_TLS_CTX(s)->ssl, ret) != SSL_ERROR_WANT_READ
                 && SSL_get_error(GET_TLS_CTX(s)->ssl, ret) != SSL_ERROR_WANT_READ)) {
    lagopus_msg_warning("tls error (%s:%d).\n", ERR_error_string((unsigned long)
                        SSL_get_error(GET_TLS_CTX(s)->ssl, ret), NULL),
                        (int) SSL_get_error(GET_TLS_CTX(s)->ssl, ret));
    return LAGOPUS_RESULT_TLS_CONN_ERROR;
  } else if (ret < 0) {
    lagopus_msg_info("tls error (%s:%d), but continue.\n",
                     ERR_error_string((unsigned long)
                                      SSL_get_error(GET_TLS_CTX(s)->ssl, ret), NULL),
                     (int) SSL_get_error(GET_TLS_CTX(s)->ssl, ret));
    return LAGOPUS_RESULT_EINPROGRESS;
  } else {
    ret = check_cert_chain(GET_TLS_CTX(s)->ssl);
    if (ret < 0) {
      lagopus_msg_warning("certificate error.\n");
      return LAGOPUS_RESULT_TLS_CONN_ERROR;
    }
    GET_TLS_CTX(s)->verified = true;
    lagopus_msg_info("tls handshake end.\n");
  }

  return LAGOPUS_RESULT_OK;
}
Пример #20
0
static inline int
s_do_main(int argc, const char *const argv[], int ipcfd) {
  lagopus_result_t st = LAGOPUS_RESULT_ANY_FAILURES;

  lagopus_msg_info("Initializing all the modules.\n");

  (void)global_state_set(GLOBAL_STATE_INITIALIZING);

  if ((st = lagopus_module_initialize_all(argc,
                                          (const char *const *)argv)) ==
      LAGOPUS_RESULT_OK &&
      s_got_term_sig == false) {

    lagopus_msg_info("All the modules are initialized.\n");

    lagopus_msg_info("Starting all the modules.\n");

    (void)global_state_set(GLOBAL_STATE_STARTING);
    if ((st = lagopus_module_start_all()) ==
        LAGOPUS_RESULT_OK &&
        s_got_term_sig == false) {
      shutdown_grace_level_t l = SHUTDOWN_UNKNOWN;

      lagopus_msg_info("All the modules are started and ready to go.\n");

      config_propagate_lagopus_conf();

      (void)global_state_set(GLOBAL_STATE_STARTED);

      if (ipcfd >= 0) {
        int zero = 0;
        (void)write(ipcfd, (void *)&zero, sizeof(int));
        (void)close(ipcfd);
        ipcfd = -1;
      }

      lagopus_msg_info("The Lagopus is a go.\n");

      s_gen_pidfile();

      while ((st = global_state_wait_for_shutdown_request(&l,
                   REQ_TIMEDOUT)) ==
             LAGOPUS_RESULT_TIMEDOUT) {
        lagopus_msg_debug(5, "Waiting for the shutdown request...\n");
      }
      if (st == LAGOPUS_RESULT_OK) {
        (void)global_state_set(GLOBAL_STATE_ACCEPT_SHUTDOWN);
        if ((st = lagopus_module_shutdown_all(l)) == LAGOPUS_RESULT_OK) {
          if ((st = lagopus_module_wait_all(s_to)) == LAGOPUS_RESULT_OK) {
            lagopus_msg_info("Shutdown succeeded.\n");
          } else if (st == LAGOPUS_RESULT_TIMEDOUT) {
          do_cancel:
            lagopus_msg_warning("Trying to stop forcibly...\n");
            if ((st = lagopus_module_stop_all()) == LAGOPUS_RESULT_OK) {
              if ((st = lagopus_module_wait_all(s_to)) ==
                  LAGOPUS_RESULT_OK) {
                lagopus_msg_warning("Stopped forcibly.\n");
              }
            }
          }
        } else if (st == LAGOPUS_RESULT_TIMEDOUT) {
          goto do_cancel;
        }
      }
    }
  }

  lagopus_module_finalize_all();

  if (st != LAGOPUS_RESULT_OK) {
    lagopus_msg_warning("Bailed out, anyway. The latest result status is:"
                        "%s\n", lagopus_error_get_string(st));
    if (ipcfd >= 0) {
      int one = 1;
      (void)write(ipcfd, (void *)&one, sizeof(int));
      (void)close(ipcfd);
    }
  }

  s_del_pidfile();

  return (st == LAGOPUS_RESULT_OK) ? 0 : 1;
}