MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
echoserver.cpp
1 /*
2  Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; see the file COPYING. If not, write to the
15  Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
16  MA 02110-1301 USA.
17 */
18 
19 /* echoserver.cpp */
20 
21 #include "../../testsuite/test.hpp"
22 
23 
24 #ifndef NO_MAIN_DRIVER
25  #define ECHO_OUT
26 
27  THREAD_RETURN YASSL_API echoserver_test(void*);
28  int main(int argc, char** argv)
29  {
30  func_args args;
31 
32  args.argc = argc;
33  args.argv = argv;
34 
35  echoserver_test(&args);
36  yaSSL_CleanUp();
37 
38  return args.return_code;
39  }
40 
41 #endif // NO_MAIN_DRIVER
42 
43 
44 
45 void EchoError(SSL_CTX* ctx, SSL* ssl, SOCKET_T& s1, SOCKET_T& s2,
46  const char* msg)
47 {
48  SSL_CTX_free(ctx);
49  SSL_free(ssl);
50  tcp_close(s1);
51  tcp_close(s2);
52  err_sys(msg);
53 }
54 
55 
56 THREAD_RETURN YASSL_API echoserver_test(void* args)
57 {
58 #ifdef _WIN32
59  WSADATA wsd;
60  WSAStartup(0x0002, &wsd);
61 #endif
62 
63  SOCKET_T sockfd = 0;
64  int argc = 0;
65  char** argv = 0;
66 
67  set_args(argc, argv, *static_cast<func_args*>(args));
68 
69 #ifdef ECHO_OUT
70  FILE* fout = stdout;
71  if (argc >= 2) fout = fopen(argv[1], "w");
72  if (!fout) err_sys("can't open output file");
73 #endif
74 
75  tcp_listen(sockfd);
76 
77  SSL_METHOD* method = SSLv23_server_method();
78  SSL_CTX* ctx = SSL_CTX_new(method);
79 
80  set_serverCerts(ctx);
81  DH* dh = set_tmpDH(ctx);
82 
83  bool shutdown(false);
84 
85 #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER)
86  // signal ready to tcp_accept
87  func_args& server_args = *((func_args*)args);
88  tcp_ready& ready = *server_args.signal_;
89  pthread_mutex_lock(&ready.mutex_);
90  ready.ready_ = true;
91  pthread_cond_signal(&ready.cond_);
92  pthread_mutex_unlock(&ready.mutex_);
93 #endif
94 
95  while (!shutdown) {
96  SOCKADDR_IN_T client;
97  socklen_t client_len = sizeof(client);
98  SOCKET_T clientfd = accept(sockfd, (sockaddr*)&client,
99  (ACCEPT_THIRD_T)&client_len);
100  if (clientfd == (SOCKET_T) -1) {
101  SSL_CTX_free(ctx);
102  tcp_close(sockfd);
103  err_sys("tcp accept failed");
104  }
105 
106  SSL* ssl = SSL_new(ctx);
107  SSL_set_fd(ssl, clientfd);
108  if (SSL_accept(ssl) != SSL_SUCCESS) {
109  printf("SSL_accept failed\n");
110  SSL_free(ssl);
111  tcp_close(clientfd);
112  continue;
113  }
114 
115  char command[1024];
116  int echoSz(0);
117  while ( (echoSz = SSL_read(ssl, command, sizeof(command))) > 0) {
118 
119  if ( strncmp(command, "quit", 4) == 0) {
120  printf("client sent quit command: shutting down!\n");
121  shutdown = true;
122  break;
123  }
124  else if ( strncmp(command, "GET", 3) == 0) {
125  char type[] = "HTTP/1.0 200 ok\r\nContent-type:"
126  " text/html\r\n\r\n";
127  char header[] = "<html><body BGCOLOR=\"#ffffff\">\n<pre>\n";
128  char body[] = "greetings from yaSSL\n";
129  char footer[] = "</body></html>\r\n\r\n";
130 
131  strncpy(command, type, sizeof(type));
132  echoSz = sizeof(type) - 1;
133 
134  strncpy(&command[echoSz], header, sizeof(header));
135  echoSz += sizeof(header) - 1;
136  strncpy(&command[echoSz], body, sizeof(body));
137  echoSz += sizeof(body) - 1;
138  strncpy(&command[echoSz], footer, sizeof(footer));
139  echoSz += sizeof(footer);
140 
141  if (SSL_write(ssl, command, echoSz) != echoSz)
142  EchoError(ctx, ssl, sockfd, clientfd, "SSL_write failed");
143 
144  break;
145  }
146  command[echoSz] = 0;
147 
148  #ifdef ECHO_OUT
149  fputs(command, fout);
150  #endif
151 
152  if (SSL_write(ssl, command, echoSz) != echoSz)
153  EchoError(ctx, ssl, sockfd, clientfd, "SSL_write failed");
154  }
155  SSL_shutdown(ssl);
156  SSL_free(ssl);
157  tcp_close(clientfd);
158  }
159 
160  tcp_close(sockfd);
161 
162  DH_free(dh);
163  SSL_CTX_free(ctx);
164 
165  ((func_args*)args)->return_code = 0;
166  return 0;
167 }