ctx = InitCTX();
/* Create the socket. The three arguments are:
* * 1) Internet domain
* * 2) Stream Socket
* * 3) Default Protocol (TCP in this case)
* * */
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
printf("\nCreated client socket = %d\n",clientSocket);
/* Configure settings of the server address struct
* * Address Family = Internet
* * Set port number , using htons() to use proper byte order
* * Set IP add of remote server
* * Set al padding bits field to 0
* * */
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(443);
serverAddr.sin_addr.s_addr = inet_addr(arg);
memset(serverAddr.sin_zero, '\0', sizeof(serverAddr.sin_zero));
addr_size = sizeof(serverAddr);
if ((connect(clientSocket, (struct sockaddr*)&serverAddr, addr_size)) == 0) {
ssl = SSL_new(ctx); /* create new SSL connection state */
SSL_set_fd(ssl, clientSocket); /* attach the socket descriptor */
这是我的 InitCTX() 定义:
SSL_CTX* InitCTX(void)
{ SSL_METHOD *method = NULL;
SSL_CTX *ctx = NULL;
method = TLS_method();
printf("\n method: %d", method);
/* method = TLSv1_2_client_method(); * Create new client-method instance */
ctx = SSL_CTX_new(method); /* Create new context */
if ( ctx == NULL )
{
ERR_print_errors_fp(stderr);
abort();
}
return ctx;
}
下面是 gdb 的调试输出:
Thread 1 "client" hit Breakpoint 1, InitCTX () at mockclient_util.c:30
30 { SSL_METHOD *method = NULL;
(gdb) s
[New Thread 0x7fffeeffd640 (LWP 21600)]
31 SSL_CTX *ctx = NULL;
(gdb)
[New Thread 0x7fffee7fc640 (LWP 21601)]
32 method = TLS_method();
(gdb)
33 printf("\n method: %d", method);
(gdb) p method
$1 = (SSL_METHOD *) 0x7ffff7f9c2c0
(gdb) ptype method
type = struct ssl_method_st {
<incomplete type>
}
(gdb) s
__printf (format=0x555555567860 "\n method: %d") at ./stdio-common/printf.c:28
28 ./stdio-common/printf.c: No such file or directory.
(gdb) fin
Run till exit from #0 __printf (format=0x555555567860 "\n method: %d") at ./stdio-common/printf.c:28
Input IP = xx.xx.xx.xx
InitCTX () at mockclient_util.c:35
35 ctx = SSL_CTX_new(method); /* Create new context */
Value returned is $2 = 20
(gdb) p ctx
$3 = (SSL_CTX *) 0x0
(gdb) ptype ctx
type = struct ssl_ctx_st {
<incomplete type>
}
(gdb)
还有打印p方法:(SSL_METHOD *) 0x7ffff7f9c2c0 和 p ctx:(SSL_CTX *)0x555555582c70 和 p * ctx: $6 = 不完整类型 和p*方法: $7 = 不完整类型
给出相邻输出^^
但是方法不是NULL,我已经用NULL检查进行了检查,这告诉TLS_method肯定不会返回NULL,但为什么它是不完整的结构
为什么结构不完整
因为结构体是前向声明的,它的定义不可用。
这是一个显示正在发生的事情的示例:
// foo.c
struct Foo {
int x;
};
static struct Foo foo;
struct Foo *fn() { return &foo; }
// x.c
struct Foo; // forward declaration
struct Foo *fn();
int main()
{
struct Foo *foo = fn();
return 0;
}
gcc -c foo.c && gcc -g x.c foo.o && gdb -q ./a.out
(gdb) start
Temporary breakpoint 1 at 0x1131: file x.c, line 5.
Starting program: /tmp/a.out
Temporary breakpoint 1, main () at x.c:5
5 struct Foo *foo = fn();
(gdb) n
6 return 0;
(gdb) p foo
$1 = (struct Foo *) 0x555555558014 <foo>
(gdb) p *foo
$2 = <incomplete type>
请注意,
foo.c
是在没有调试信息的情况下编译的(没有-g
标志)。如果您使用调试信息构建它,则情况会发生变化:
gcc -g x.c foo.c && gdb -q ./a.out
(gdb) start
Temporary breakpoint 1 at 0x1131: file x.c, line 5.
Starting program: /tmp/a.out
Temporary breakpoint 1, main () at x.c:5
5 struct Foo *foo = fn();
(gdb) n
6 return 0;
(gdb) p foo
$1 = (struct Foo *) 0x555555558014 <foo>
(gdb) p *foo
$2 = {x = 0} <<<=== definition of Foo is available in foo.c
结论:您想要链接到 libssl.a
的调试版本,或者如果使用
libssl.so
,您需要为其安装调试信息(由您的发行版作为单独的包提供)。