int swPort_enable_ssl_encrypt(swListenPort *ls) { if (ls->ssl_cert_file == NULL || ls->ssl_key_file == NULL) { swWarn("SSL error, require ssl_cert_file and ssl_key_file."); return SW_ERR; } ls->ssl_context = swSSL_get_context(ls->ssl_method, ls->ssl_cert_file, ls->ssl_key_file); if (ls->ssl_context == NULL) { swWarn("swSSL_get_context() error."); return SW_ERR; } if (ls->ssl_client_cert_file && swSSL_set_client_certificate(ls->ssl_context, ls->ssl_client_cert_file, ls->ssl_verify_depth) == SW_ERR) { swWarn("swSSL_set_client_certificate() error."); return SW_ERR; } if (ls->open_http_protocol) { ls->ssl_config.http = 1; } if (ls->open_http2_protocol) { ls->ssl_config.http_v2 = 1; swSSL_server_http_advise(ls->ssl_context, &ls->ssl_config); } if (swSSL_server_set_cipher(ls->ssl_context, &ls->ssl_config) < 0) { swWarn("swSSL_server_set_cipher() error."); return SW_ERR; } return SW_OK; }
int swPort_listen(swListenPort *ls) { if (swSocket_is_dgram(ls->type)) { int sock = swSocket_listen(ls->type, ls->host, ls->port, ls->backlog); if (sock < 0) { return SW_ERR; } int bufsize = SwooleG.socket_buffer_size; setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)); setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)); ls->sock = sock; return sock; } #ifdef SW_USE_OPENSSL if (ls->open_ssl_encrypt) { if (ls->ssl_cert_file == NULL || ls->ssl_key_file == NULL) { swWarn("SSL error, require ssl_cert_file and ssl_key_file."); return SW_ERR; } ls->ssl_context = swSSL_get_context(ls->ssl_method, ls->ssl_cert_file, ls->ssl_key_file); if (ls->ssl_context == NULL) { return SW_ERR; } if (ls->ssl_client_cert_file && swSSL_set_client_certificate(ls->ssl_context, ls->ssl_client_cert_file, ls->ssl_verify_depth) == SW_ERR) { return SW_ERR; } } if (ls->ssl) { if (!ls->ssl_cert_file) { swWarn("need to configure [server->ssl_cert_file]."); return SW_ERR; } if (!ls->ssl_key_file) { swWarn("need to configure [server->ssl_key_file]."); return SW_ERR; } } #endif //TCP int sock = swSocket_listen(ls->type, ls->host, ls->port, ls->backlog); if (sock < 0) { return SW_ERR; } #ifdef TCP_DEFER_ACCEPT if (ls->tcp_defer_accept) { if (setsockopt(sock, IPPROTO_TCP, TCP_DEFER_ACCEPT, (const void*) &ls->tcp_defer_accept, sizeof(int)) < 0) { swSysError("setsockopt(TCP_DEFER_ACCEPT) failed."); } } #endif #ifdef TCP_FASTOPEN if (ls->tcp_fastopen) { if (setsockopt(sock, IPPROTO_TCP, TCP_FASTOPEN, (const void*) &ls->tcp_fastopen, sizeof(int)) < 0) { swSysError("setsockopt(TCP_FASTOPEN) failed."); } } #endif #ifdef SO_KEEPALIVE int sockopt; if (ls->open_tcp_keepalive == 1) { sockopt = 1; if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *) &sockopt, sizeof(int)) < 0) { swSysError("setsockopt(SO_KEEPALIVE) failed."); } #ifdef TCP_KEEPIDLE setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, (void*) &ls->tcp_keepidle, sizeof(int)); setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, (void *) &ls->tcp_keepinterval, sizeof(int)); setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, (void *) &ls->tcp_keepcount, sizeof(int)); #endif } #endif return sock; }
int swPort_set_option(swListenPort *ls) { int sock = ls->sock; //reuse address int option = 1; //reuse port #ifdef HAVE_REUSEPORT if (SwooleG.reuse_port) { if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &option, sizeof(int)) < 0) { swSysError("setsockopt(SO_REUSEPORT) failed."); SwooleG.reuse_port = 0; } } #endif if (swSocket_is_dgram(ls->type)) { int bufsize = SwooleG.socket_buffer_size; setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)); setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)); return SW_OK; } #ifdef SW_USE_OPENSSL if (ls->open_ssl_encrypt) { if (ls->ssl_cert_file == NULL || ls->ssl_key_file == NULL) { swWarn("SSL error, require ssl_cert_file and ssl_key_file."); return SW_ERR; } ls->ssl_context = swSSL_get_context(ls->ssl_method, ls->ssl_cert_file, ls->ssl_key_file); if (ls->ssl_context == NULL) { swWarn("swSSL_get_context() error."); return SW_ERR; } if (ls->ssl_client_cert_file && swSSL_set_client_certificate(ls->ssl_context, ls->ssl_client_cert_file, ls->ssl_verify_depth) == SW_ERR) { swWarn("swSSL_set_client_certificate() error."); return SW_ERR; } if (ls->open_http_protocol) { ls->ssl_config.http = 1; } if (ls->open_http2_protocol) { ls->ssl_config.http_v2 = 1; swSSL_server_http_advise(ls->ssl_context, &ls->ssl_config); } if (swSSL_server_set_cipher(ls->ssl_context, &ls->ssl_config) < 0) { swWarn("swSSL_server_set_cipher() error."); return SW_ERR; } } if (ls->ssl) { if (!ls->ssl_cert_file) { swWarn("need to set [ssl_cert_file] option."); return SW_ERR; } if (!ls->ssl_key_file) { swWarn("need to set [ssl_key_file] option."); return SW_ERR; } } #endif //listen stream socket if (listen(sock, ls->backlog) < 0) { swWarn("listen(%s:%d, %d) failed. Error: %s[%d]", ls->host, ls->port, ls->backlog, strerror(errno), errno); return SW_ERR; } #ifdef TCP_DEFER_ACCEPT if (ls->tcp_defer_accept) { if (setsockopt(sock, IPPROTO_TCP, TCP_DEFER_ACCEPT, (const void*) &ls->tcp_defer_accept, sizeof(int)) < 0) { swSysError("setsockopt(TCP_DEFER_ACCEPT) failed."); } } #endif #ifdef TCP_FASTOPEN if (ls->tcp_fastopen) { if (setsockopt(sock, IPPROTO_TCP, TCP_FASTOPEN, (const void*) &ls->tcp_fastopen, sizeof(int)) < 0) { swSysError("setsockopt(TCP_FASTOPEN) failed."); } } #endif #ifdef SO_KEEPALIVE if (ls->open_tcp_keepalive == 1) { option = 1; if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *) &option, sizeof(option)) < 0) { swSysError("setsockopt(SO_KEEPALIVE) failed."); } #ifdef TCP_KEEPIDLE setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, (void*) &ls->tcp_keepidle, sizeof(int)); setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, (void *) &ls->tcp_keepinterval, sizeof(int)); setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, (void *) &ls->tcp_keepcount, sizeof(int)); #endif } #endif return SW_OK; }