1 module yu.asyncsocket.sslsocket; 2 3 version (USE_SSL) : import core.stdc.errno; 4 import core.stdc.string; 5 6 import core.thread; 7 8 import std.string; 9 import std.socket; 10 import std.exception; 11 import std.experimental.logger; 12 13 import yu.eventloop; 14 import yu.asyncsocket.transport; 15 import yu.asyncsocket.tcpsocket; 16 import yu.exception; 17 18 import deimos.openssl.ssl; 19 import deimos.openssl.bio; 20 21 @trusted class SSLSocket : TCPSocket { 22 static if (IOMode == IO_MODE.iocp) { 23 this(EventLoop loop, Socket sock, SSL * ssl, BIO * bioRead, BIO * bioWrite) { 24 super(loop, sock); 25 _ssl = ssl; 26 _bioIn = bioRead; 27 _bioOut = bioWrite; 28 _rBuffer = makeArray!ubyte(yuAlloctor, TCP_READ_BUFFER_SIZE); 29 _wBuffer = makeArray!ubyte(yuAlloctor, TCP_READ_BUFFER_SIZE); 30 } 31 } else { 32 this(EventLoop loop, Socket sock, SSL * ssl) { 33 super(loop, sock); 34 _ssl = ssl; 35 } 36 } 37 38 ~this() { 39 if (_ssl) { 40 SSL_shutdown(_ssl); 41 SSL_free(_ssl); 42 _ssl = null; 43 _bioIn = null; 44 _bioOut = null; 45 } 46 static if (IOMode == IO_MODE.iocp) { 47 yDel(_rBuffer); 48 yDel(_wBuffer); 49 } 50 } 51 52 override @property bool isAlive() @trusted nothrow { 53 return alive() && _isHandshaked; 54 } 55 56 pragma(inline) void setHandshakeCallBack(CallBack cback) { 57 _handshakeCback = cback; 58 } 59 60 protected : override void onClose() { 61 if (_ssl) { 62 SSL_shutdown(_ssl); 63 SSL_free(_ssl); 64 _ssl = null; 65 _bioIn = null; 66 _bioOut = null; 67 } 68 super.onClose(); 69 } 70 static if (IOMode == IO_MODE.iocp) { 71 72 override void onWrite() { 73 if (writeBIOtoSocket() || _writeQueue.empty) 74 return; 75 try { 76 if (_lastWrite > 0) { 77 auto buffer = _writeQueue.front; 78 if (buffer.add(_lastWrite)) { 79 _writeQueue.deQueue().doCallBack(); 80 } 81 } 82 if (!alive || _writeQueue.empty) 83 return; 84 auto buffer = _writeQueue.front; 85 _lastWrite = SSL_write(_ssl, buffer.data.ptr, cast(int) buffer.length); // data中存放了要发送的数据 86 writeBIOtoSocket(); 87 } 88 catch (Exception e) { 89 showException(e); 90 } 91 } 92 override void onRead() { 93 try { 94 if (!alive) 95 return; 96 //trace("read data : data.length: ", _event.readLen); 97 if (_event.readLen > 0) { 98 BIO_write(_bioIn, _readBuffer.ptr, cast(int) _event.readLen); 99 if (!_isHandshaked) { 100 if (!handlshake()) { 101 _event.readLen = 0; 102 doRead(); 103 return; 104 } 105 onWrite(); 106 } 107 while (true) { 108 int ret = SSL_read(_ssl, _rBuffer.ptr, cast(int) _rBuffer.length); 109 if (ret > 0) { 110 _readCallBack(_rBuffer[0 .. ret]); 111 continue; 112 } else { 113 break; 114 } 115 } 116 } else { 117 onClose(); 118 return; 119 } 120 } 121 catch (Exception e) { 122 showException(e); 123 } 124 _event.readLen = 0; 125 if (alive) 126 doRead(); 127 } 128 bool writeBIOtoSocket() nothrow { 129 if (!alive) 130 return true; 131 int hasread = BIO_read(_bioOut, _wBuffer.ptr, cast(int) _wBuffer.length); 132 if (hasread > 0) { 133 _iocpWBuf.len = hasread; 134 _iocpWBuf.buf = cast(char * ) _wBuffer.ptr; 135 _event.writeLen = 0; 136 doWrite(); 137 return true; 138 } 139 return false; 140 } 141 } else { 142 override void onWrite() { 143 if (alive && !_isHandshaked) { 144 if (!handlshake()) 145 return; 146 } 147 try { 148 while (alive && !_writeQueue.empty) { 149 auto buffer = _writeQueue.front; 150 auto len = SSL_write(_ssl, buffer.data.ptr, cast(int) buffer.length); // _socket.send(buffer.data); 151 if (len > 0) { 152 if (buffer.add(len)) { 153 _writeQueue.deQueue().doCallBack(); 154 } 155 continue; 156 } else { 157 int sslerron = SSL_get_error(_ssl, len); 158 if (sslerron == SSL_ERROR_WANT_READ || errno == EWOULDBLOCK 159 || errno == EAGAIN) 160 break; 161 else if (errno == 4) // erro 4 :系统中断组织了 162 continue; 163 } 164 error("write size: ", len, 165 " \n\tDo Close the erro code : ", errno, 166 " erro is : ", fromStringz(strerror(errno)), " \n\tthe socket fd : ", 167 fd); 168 onClose(); 169 return; 170 } 171 } 172 catch (Exception e) { 173 import yu.exception; 174 175 showException(e); 176 onClose(); 177 return; 178 } 179 } 180 181 override void onRead() { 182 try { 183 while (alive) { 184 if (!_isHandshaked) { 185 if (!handlshake()) 186 return; 187 } 188 auto len = SSL_read(_ssl, (_readBuffer.ptr), cast(int)(_readBuffer.length)); 189 if (len > 0) { 190 _readCallBack(_readBuffer[0 .. len]); 191 continue; 192 } else if (len < 0) { 193 int sslerron = SSL_get_error(_ssl, len); 194 if (sslerron == SSL_ERROR_WANT_READ || errno == EWOULDBLOCK 195 || errno == EAGAIN) 196 break; 197 else if (errno == 4) // erro 4 :系统中断组织了 198 continue; 199 import core.stdc.string; 200 201 error("Do Close the erro code : ", errno, 202 " erro is : ", fromStringz(strerror(errno)), 203 " \n\tthe socket fd : ", fd); 204 } 205 onClose(); 206 return; 207 } 208 } 209 catch (Exception e) { 210 import yu.exception; 211 212 showException(e); 213 onClose(); 214 } 215 } 216 } 217 final bool handlshake() nothrow { 218 int r = SSL_do_handshake(_ssl); 219 static if (IOMode == IO_MODE.iocp) 220 writeBIOtoSocket(); 221 if (r == 1) { 222 _isHandshaked = true; 223 if (_handshakeCback) { 224 _handshakeCback(); 225 } 226 return true; 227 } 228 int err = SSL_get_error(_ssl, r); 229 if (err == SSL_ERROR_WANT_WRITE) { 230 static if (IOMode == IO_MODE.iocp) 231 writeBIOtoSocket(); 232 return false; 233 } else if (err == SSL_ERROR_WANT_READ) { 234 return false; 235 } else { 236 yuCathException(error("SSL_do_handshake return: ", r, " erro :", 237 err, " errno:", errno, " erro string:", fromStringz(strerror(errno)))); 238 onClose(); 239 return false; 240 } 241 } 242 243 protected : bool _isHandshaked = false; 244 245 private : SSL * _ssl; 246 CallBack _handshakeCback; 247 static if (IOMode == IO_MODE.iocp) { 248 BIO * _bioIn; 249 BIO * _bioOut; 250 ubyte[] _rBuffer; 251 ubyte[] _wBuffer; 252 ptrdiff_t _lastWrite = 0; 253 } 254 }