1 module mysql.socket;
2 
3 import vibe.core.net;
4 import vibe.core.stream;
5 import vibe.stream.tls;
6 import vibe.stream.wrapper;
7 
8 import mysql.ssl;
9 
10 struct VibeSocket {
11 	void connect(const(char)[] host, ushort port) {
12 		socket_ = connectTCP(cast(string)host, port);
13 		socket_.keepAlive = true;
14 		socket_.tcpNoDelay = true;
15 		static if (is(StreamProxy)) {
16 			stream_ = createProxyStream(socket_);
17 		} else {
18 			stream_ = socket_;
19 		}
20 	}
21 
22 	bool connected() inout {
23 		return socket_ && socket_.connected();
24 	}
25 
26 	void close() {
27 		if (socket_) {
28 			socket_.close();
29 			static if (is(typeof(socket_) == class)) {
30 				socket_ = null;
31 			}
32 		}
33 	}
34 
35 	void read(ubyte[] buffer) {
36 		stream_.read(buffer);
37 	}
38 
39 	void write(in ubyte[] buffer) {
40 		stream_.write(buffer);
41 	}
42 
43 	void flush() {
44 		stream_.flush();
45 	}
46 
47 	bool empty() {
48 		return stream_.empty;
49 	}
50 
51 	void startSSL(const(char)[] hostName, SSLConfig config) {
52 		TLSVersion tlsVersion;
53 
54 		final switch (config.sslVersion) with (SSLConfig.Version) {
55 		case any:
56 			tlsVersion = TLSVersion.any;
57 			break;
58 		case ssl3:
59 			tlsVersion = TLSVersion.ssl3;
60 			break;
61 		case tls1:
62 			tlsVersion = TLSVersion.tls1;
63 			break;
64 		case tls1_1:
65 			tlsVersion = TLSVersion.tls1_1;
66 			break;
67 		case tls1_2:
68 			tlsVersion = TLSVersion.tls1_2;
69 			break;
70 		case dtls1:
71 			tlsVersion = TLSVersion.dtls1;
72 			break;
73 		}
74 
75 		TLSPeerValidationMode peerValidationMode;
76 
77 		final switch (config.validate) with (SSLConfig.Validate) {
78 		case basic:
79 			peerValidationMode = TLSPeerValidationMode.checkCert | TLSPeerValidationMode.requireCert;
80 			break;
81 		case trust:
82 			peerValidationMode = TLSPeerValidationMode.checkCert | TLSPeerValidationMode.requireCert | TLSPeerValidationMode.checkTrust;
83 			break;
84 		case identity:
85 			peerValidationMode = TLSPeerValidationMode.checkCert | TLSPeerValidationMode.requireCert | TLSPeerValidationMode.checkTrust | TLSPeerValidationMode.checkPeer;
86 			break;
87 		}
88 
89 		auto ctx = createTLSContext(TLSContextKind.client, tlsVersion);
90 		ctx.peerValidationMode = peerValidationMode;
91 
92 		if (config.rootCertFile.length)
93 			ctx.useTrustedCertificateFile(config.rootCertFile.idup);
94 
95 		if (config.ciphers.length)
96 			ctx.setCipherList(config.ciphers.idup);
97 
98 		auto peerName = config.hostName.length ? config.hostName : hostName;
99 
100 		stream_ = createTLSStream(socket_, ctx, TLSStreamState.connecting, peerName.idup, socket_.remoteAddress);
101 	}
102 
103 private:
104 	TCPConnection socket_;
105 	static if (is(StreamProxy)) {
106 		StreamProxy stream_;
107 	} else {
108 		Stream stream_;
109 	}
110 }