Skip to content

Commit

Permalink
TLS support
Browse files Browse the repository at this point in the history
  • Loading branch information
kshvakov committed Nov 1, 2017
1 parent 9beaf18 commit d1203a3
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 4 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ Golang SQL database driver for [Yandex ClickHouse](https://clickhouse.yandex/)
* block_size - maximum rows in block (default is 1000000). If the rows are larger then the data will be split into several blocks to send them to the server
* debug - enable debug output (boolean value)

SSL/TLS parameters:

* secure - establish secure connection (default is false)
* skip_verify - skip certificate verification (default is true)

example:
```
tcp://host1:9000?username=user&password=qwerty&database=clicks&read_timeout=10&write_timeout=20&alt_hosts=host2:9000,host3:9000
Expand Down
10 changes: 9 additions & 1 deletion bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ func open(dsn string) (*clickhouse, error) {
var (
hosts = []string{url.Host}
query = url.Query()
secure = false
skipVerify = true
noDelay = true
compress = false
database = query.Get("database")
Expand All @@ -67,6 +69,12 @@ func open(dsn string) (*clickhouse, error) {
if v, err := strconv.ParseBool(query.Get("no_delay")); err == nil && !v {
noDelay = false
}
if v, err := strconv.ParseBool(query.Get("secure")); err == nil && v {
secure = true
}
if v, err := strconv.ParseBool(query.Get("skip_verify")); err == nil && !v {
skipVerify = false
}
if duration, err := strconv.ParseFloat(query.Get("read_timeout"), 64); err == nil {
readTimeout = time.Duration(duration * float64(time.Second))
}
Expand Down Expand Up @@ -115,7 +123,7 @@ func open(dsn string) (*clickhouse, error) {
database,
username,
)
if ch.conn, err = dial("tcp", hosts, noDelay, connOpenStrategy, ch.logf); err != nil {
if ch.conn, err = dial(secure, skipVerify, hosts, noDelay, connOpenStrategy, ch.logf); err != nil {
return nil, err
}
logger.SetPrefix(fmt.Sprintf("[clickhouse][connect=%d]", ch.conn.ident))
Expand Down
21 changes: 18 additions & 3 deletions connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package clickhouse

import (
"bufio"
"crypto/tls"
"database/sql/driver"
"net"
"sync/atomic"
Expand All @@ -25,7 +26,7 @@ const (
connOpenInOrder
)

func dial(network string, hosts []string, noDelay bool, openStrategy openStrategy, logf func(string, ...interface{})) (*connect, error) {
func dial(secure, skipVerify bool, hosts []string, noDelay bool, openStrategy openStrategy, logf func(string, ...interface{})) (*connect, error) {
var (
err error
abs = func(v int) int {
Expand All @@ -45,8 +46,22 @@ func dial(network string, hosts []string, noDelay bool, openStrategy openStrateg
case connOpenRandom:
num = (ident + 1) % len(hosts)
}
if conn, err = net.DialTimeout(network, hosts[num], 20*time.Second); err == nil {
logf("[dial] strategy=%s, ident=%d, server=%d -> %s", openStrategy, ident, num, conn.RemoteAddr())
switch {
case secure:
conn, err = tls.DialWithDialer(
&net.Dialer{
Timeout: 5 * time.Second,
},
"tcp",
hosts[num],
&tls.Config{
InsecureSkipVerify: skipVerify,
})
default:
conn, err = net.DialTimeout("tcp", hosts[num], 5*time.Second)
}
if err == nil {
logf("[dial] secure=%t, skip_verify=%t, strategy=%s, ident=%d, server=%d -> %s", secure, skipVerify, openStrategy, ident, num, conn.RemoteAddr())
if tcp, ok := conn.(*net.TCPConn); ok {
tcp.SetNoDelay(noDelay) // Disable or enable the Nagle Algorithm for this tcp socket
}
Expand Down

0 comments on commit d1203a3

Please sign in to comment.