1 /*
2 * Copyright (c) 2023 Unionman Technology Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "server_process.h"
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <sys/types.h>
22 #include <unistd.h>
23 #include <winsock2.h>
24 #include <ws2tcpip.h>
25
26 #include "openssl/err.h"
27 #include "openssl/ssl.h"
28
29 #define SERVER_PEM "config/serverKey.pem"
30 #define SERVER_CER "config/serverCert.cer"
31 #define SRVER_PROFILE "config/serverInfo.json"
32 #define PORT_NUMBER 5022
33
34 static int s_sockfd = -1;
35 static SSL_CTX* s_ctx = NULL;
36 static SSL* ssl = NULL;
37
38
39 #define LOG_PRINT(fmt, ...) printf("[ServerProcess][%s:%d] " fmt "\n", __func__, __LINE__, ##__VA_ARGS__)
40 #define DO_CHECK(cond, log, ...) \
41 if (!(cond)) { \
42 LOG_PRINT(log); \
43 __VA_ARGS__; \
44 }
45
46
47 char* respondContent = NULL;
48
readServerProfileFromLocal(void)49 int readServerProfileFromLocal(void)
50 {
51 // write file
52 const char* file_name = SRVER_PROFILE;
53 FILE* serverProfileFile = fopen(file_name, "rb");
54
55 if (serverProfileFile == NULL) {
56 printf("serverInfo.json is not exist.");
57 return -1;
58 }
59
60 (void)fseek(serverProfileFile, 0, SEEK_END);
61 long fileSize = ftell(serverProfileFile);
62 (void)fseek(serverProfileFile, 0, SEEK_SET);
63
64 if (fileSize < 0) {
65 return -1;
66 }
67 respondContent = (char*)malloc(fileSize + 1);
68 size_t len = fread(respondContent, 1, fileSize, serverProfileFile);
69 if (len < 0) {
70 return -1;
71 }
72 respondContent[len] = 0;
73
74 (void)fclose(serverProfileFile);
75
76 return 0;
77 }
78
79 /* 创建socket环境 */
Init(void)80 int Init(void)
81 {
82 struct sockaddr_in serverAddr = { 0 };
83 int sockfd;
84 {
85 WSADATA data;
86 WSAStartup(MAKEWORD(2L, 2L), &data);
87 }
88 sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
89 DO_CHECK(sockfd != -1, "Failed to create socket");
90
91 serverAddr.sin_family = AF_INET;
92 serverAddr.sin_addr.s_addr = INADDR_ANY;
93 serverAddr.sin_port = htons(PORT_NUMBER); /* 端口号 */
94
95 DO_CHECK(bind(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == 0, "Failed to bind socket");
96 DO_CHECK(listen(sockfd, SOMAXCONN) == 0, "Failed to listen on socket");
97 LOG_PRINT("Server is listening on port 5022 ");
98 s_sockfd = sockfd;
99 return 0;
100 }
101
102
103 /* 服务打开的接口 */
Open(void)104 int Open(void)
105 {
106 const SSL_METHOD* method;
107 SSL_CTX* ctx;
108
109 SSL_library_init();
110 SSL_load_error_strings();
111 method = TLS_server_method(); /* 使用TLS v1.2作为方法 */
112 ctx = SSL_CTX_new(method);
113 if (!ctx) {
114 ERR_print_errors_fp(stderr);
115 return -1;
116 }
117 if (SSL_CTX_use_certificate_file(ctx, SERVER_CER, SSL_FILETYPE_PEM) <= 0) {
118 ERR_print_errors_fp(stderr);
119 return -1;
120 }
121 if (SSL_CTX_use_PrivateKey_file(ctx, SERVER_PEM, SSL_FILETYPE_PEM) <= 0) {
122 ERR_print_errors_fp(stderr);
123 return -1;
124 }
125
126 s_ctx = ctx;
127 return 0;
128 }
129
130
131 /* 每隔100ms调用一次 */
MainLoop(void)132 int MainLoop(void)
133 {
134 /* 接受连接 */
135 int accfd = accept(s_sockfd, NULL, NULL);
136
137 DO_CHECK(readServerProfileFromLocal() == 0, "Failed to read ServerProfile");
138
139 /* 创建 SSL 上下文 */
140 SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method());
141
142 /* 载入数字证书和私钥 */
143 SSL_CTX_use_certificate_file(ctx, SERVER_CER, SSL_FILETYPE_PEM);
144 SSL_CTX_use_PrivateKey_file(ctx, SERVER_PEM, SSL_FILETYPE_PEM);
145
146 /* 创建 SSL 对象 */
147 SSL* ssl = SSL_new(ctx);
148 SSL_set_fd(ssl, accfd);
149
150 /* 建立 SSL 连接 */
151 if (SSL_accept(ssl) == -1) {
152 perror("SSL_accept");
153 close(accfd);
154 return 0;
155 }
156
157 /* 发送数据 */
158 SSL_write(ssl, respondContent, strlen(respondContent));
159
160 /* 接收数据 */
161 char buf[1024];
162 int len = SSL_read(ssl, buf, sizeof(buf));
163 buf[len] = '\0';
164 printf("Received: %s\n", buf);
165
166 /* 关闭连接套接字 */
167 usleep(100000L);
168 close(accfd);
169 return 0;
170 }
171
172 /* 关闭服务并释放资源 */
Close(void)173 int Close(void)
174 {
175 /* 关闭 SSL 连接 */
176 SSL_shutdown(ssl);
177 SSL_free(ssl);
178 SSL_CTX_free(s_ctx);
179 WSACleanup();
180 close(s_sockfd);
181 s_sockfd = NULL;
182 return 0;
183 }
184