1/* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20package thrift 21 22import ( 23 "crypto/tls" 24 "net" 25 "time" 26) 27 28type TSSLServerSocket struct { 29 listener net.Listener 30 addr net.Addr 31 clientTimeout time.Duration 32 interrupted bool 33 cfg *tls.Config 34} 35 36func NewTSSLServerSocket(listenAddr string, cfg *tls.Config) (*TSSLServerSocket, error) { 37 return NewTSSLServerSocketTimeout(listenAddr, cfg, 0) 38} 39 40func NewTSSLServerSocketTimeout(listenAddr string, cfg *tls.Config, clientTimeout time.Duration) (*TSSLServerSocket, error) { 41 if cfg.MinVersion == 0 { 42 cfg.MinVersion = tls.VersionTLS10 43 } 44 addr, err := net.ResolveTCPAddr("tcp", listenAddr) 45 if err != nil { 46 return nil, err 47 } 48 return &TSSLServerSocket{addr: addr, clientTimeout: clientTimeout, cfg: cfg}, nil 49} 50 51func (p *TSSLServerSocket) Listen() error { 52 if p.IsListening() { 53 return nil 54 } 55 l, err := tls.Listen(p.addr.Network(), p.addr.String(), p.cfg) 56 if err != nil { 57 return err 58 } 59 p.listener = l 60 return nil 61} 62 63func (p *TSSLServerSocket) Accept() (TTransport, error) { 64 if p.interrupted { 65 return nil, errTransportInterrupted 66 } 67 if p.listener == nil { 68 return nil, NewTTransportException(NOT_OPEN, "No underlying server socket") 69 } 70 conn, err := p.listener.Accept() 71 if err != nil { 72 return nil, NewTTransportExceptionFromError(err) 73 } 74 return NewTSSLSocketFromConnTimeout(conn, p.cfg, p.clientTimeout), nil 75} 76 77// Checks whether the socket is listening. 78func (p *TSSLServerSocket) IsListening() bool { 79 return p.listener != nil 80} 81 82// Connects the socket, creating a new socket object if necessary. 83func (p *TSSLServerSocket) Open() error { 84 if p.IsListening() { 85 return NewTTransportException(ALREADY_OPEN, "Server socket already open") 86 } 87 if l, err := tls.Listen(p.addr.Network(), p.addr.String(), p.cfg); err != nil { 88 return err 89 } else { 90 p.listener = l 91 } 92 return nil 93} 94 95func (p *TSSLServerSocket) Addr() net.Addr { 96 return p.addr 97} 98 99func (p *TSSLServerSocket) Close() error { 100 defer func() { 101 p.listener = nil 102 }() 103 if p.IsListening() { 104 return p.listener.Close() 105 } 106 return nil 107} 108 109func (p *TSSLServerSocket) Interrupt() error { 110 p.interrupted = true 111 return nil 112} 113