keepalived源码浅析——SSL engine

来源:互联网 发布:淘宝买家信誉评价 编辑:程序博客网 时间:2024/05/18 18:46

ssl.h源码:

#ifndef _SSL_H#define _SSL_H#include <openssl/ssl.h>/* Prototypes */extern void init_ssl(void);extern int ssl_connect(thread_t *);extern int ssl_printerr(int);extern int ssl_send_request(SSL *, char *, int);extern int ssl_read_thread(thread_t *);#endif



ssl.c源码:

#include <openssl/err.h>#include "main.h"#include "sock.h"#include "http.h"#include "ssl.h"#include "utils.h"#include "html.h"/* extern variables */extern REQ *req;/* * Initialize the SSL context, with or without specific * configuration files. */static BIO *bio_err = 0;voidinit_ssl(void){/* Library initialization */  // SSL 库初始化SSL_library_init();SSL_load_error_strings();bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);/* Initialize SSL context for SSL v2/3 */   //初始化SSL上下文 SSL v2/3 req->meth = (SSL_METHOD *) SSLv23_method();req->ctx = SSL_CTX_new(req->meth);#if (OPENSSL_VERSION_NUMBER < 0x00905100L)SSL_CTX_set_verify_depth(req->ctx, 1);#endif}/* Display SSL error to readable string */  // 将SSL 错误转换成可读的字符intssl_printerr(int err){unsigned long extended_error = 0;char *ssl_strerr;switch (err) {case SSL_ERROR_ZERO_RETURN:fprintf(stderr, "  SSL error: (zero return)\n");break;case SSL_ERROR_WANT_READ:fprintf(stderr, "  SSL error: (read error)\n");break;case SSL_ERROR_WANT_WRITE:fprintf(stderr, "  SSL error: (write error)\n");break;case SSL_ERROR_WANT_CONNECT:fprintf(stderr, "  SSL error: (connect error)\n");break;case SSL_ERROR_WANT_X509_LOOKUP:fprintf(stderr, "  SSL error: (X509 lookup error)\n");break;case SSL_ERROR_SYSCALL:fprintf(stderr, "  SSL error: (syscall error)\n");break;case SSL_ERROR_SSL:{ssl_strerr = (char *) MALLOC(500);extended_error = ERR_get_error();ERR_error_string(extended_error, ssl_strerr);fprintf(stderr, "  SSL error: (%s)\n", ssl_strerr);FREE(ssl_strerr);break;}}return 0;}intssl_connect(thread_t * thread)   //SSL 连接   1连接失败  0连接成功                                                                                                                                                       {SOCK *sock_obj = THREAD_ARG(thread);int ret;sock_obj->ssl = SSL_new(req->ctx);sock_obj->bio = BIO_new_socket(sock_obj->fd, BIO_NOCLOSE);BIO_set_nbio(sock_obj->bio, 1);/* Set the Non-Blocking flag */SSL_set_bio(sock_obj->ssl, sock_obj->bio, sock_obj->bio);ret = SSL_connect(sock_obj->ssl);DBG("  SSL_connect return code = %d on fd:%d\n", ret, thread->u.fd);ssl_printerr(SSL_get_error(sock_obj->ssl, ret));return (ret > 0) ? 1 : 0;}intssl_send_request(SSL * ssl, char *str_request, int request_len)  //SSL 请求 发送数据{int err, r = 0;while (1) {err = 1;r = SSL_write(ssl, str_request, request_len);if (SSL_ERROR_NONE != SSL_get_error(ssl, r))break;err++;if (request_len != r)break;err++;break;}return (err == 3) ? 1 : 0;}/* Asynchronous SSL stream reader */                  //异步的SSL 读取                                                                          intssl_read_thread(thread_t * thread){SOCK *sock_obj = THREAD_ARG(thread);int r = 0;int error;/* Handle read timeout */if (thread->type == THREAD_READ_TIMEOUT)return epilog(thread);/* * The design implemented here is a workaround for use * with OpenSSL. This goto loop is a 'read until not * end of stream'. But this break a little our global * I/O multiplexer thread framework because it enter * a synchronous read process for each GET reply. * Sound a little nasty !. *  * Why OpenSSL doesn t handle underlying fd. This * break the I/O (select()) approach !... * If you read this and know the answer, please reply * I am probably missing something... :) * My test show that sometime it return from select, * and sometime not... */      read_stream:/* read the SSL stream */memset(sock_obj->buffer, 0, MAX_BUFFER_LENGTH);  // 最大长度 #define MAX_BUFFER_LENGTH 4096r = SSL_read(sock_obj->ssl, sock_obj->buffer, MAX_BUFFER_LENGTH);error = SSL_get_error(sock_obj->ssl, r);DBG(" [l:%d,fd:%d]\n", r, sock_obj->fd);if (error) {/* All the SSL streal has been parsed *//* Handle response stream */if (error != SSL_ERROR_NONE)return finalize(thread);} else if (r > 0 && error == 0) {/* Handle the response stream */http_process_stream(sock_obj, r);/* * Register next ssl stream reader. * Register itself to not perturbe global I/O multiplexer. */goto read_stream;}return 0;}


 

其中关联的函数都在 Http.c 源码中