Skip to content

Commit

Permalink
Merge pull request #111 from keybase/mike/sigpipe
Browse files Browse the repository at this point in the history
add option to disable SIGPIPE on BSD-like systems
  • Loading branch information
mmaxim authored Mar 30, 2017
2 parents 2641a99 + cc808fc commit ed07556
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 5 deletions.
35 changes: 30 additions & 5 deletions rpc/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ func (t *connTransport) Dial(context.Context) (Transporter, error) {
if err != nil {
return nil, err
}

// Disable SIGPIPE on platforms that require it (Darwin). See sigpipe_bsd.go.
if err = DisableSigPipe(t.conn); err != nil {
return nil, err
}

t.stagedTransport = NewTransport(t.conn, t.l, t.wef)
return t.stagedTransport, nil
}
Expand Down Expand Up @@ -152,6 +158,10 @@ func (ct *ConnectionTransportTLS) Dial(ctx context.Context) (
var conn net.Conn
err := runUnlessCanceled(ctx, func() error {
config := ct.tlsConfig
host, _, err := net.SplitHostPort(ct.srvAddr)
if err != nil {
return err
}

// If we didn't specify a tls.Config, but we did specify
// explicit rootCerts, then populate a new tls.Config here.
Expand All @@ -162,14 +172,29 @@ func (ct *ConnectionTransportTLS) Dial(ctx context.Context) (
if !certs.AppendCertsFromPEM(ct.rootCerts) {
return errors.New("Unable to load root certificates")
}
config = &tls.Config{RootCAs: certs}
config = &tls.Config{
RootCAs: certs,
ServerName: host,
}
}
// Final check to make sure we have a TLS config since tls.Client requires
// either ServerName or InsecureSkipVerify to be set.
if config == nil {
config = &tls.Config{ServerName: host}
}

// connect
var err error
conn, err = tls.DialWithDialer(&net.Dialer{
dialer := net.Dialer{
KeepAlive: 10 * time.Second,
}, "tcp", ct.srvAddr, config)
return err
}
baseConn, err := dialer.Dial("tcp", ct.srvAddr)
if err != nil {
return err
}
conn = tls.Client(baseConn, config)

// Disable SIGPIPE on platforms that require it (Darwin). See sigpipe_bsd.go.
return DisableSigPipe(baseConn)
})
if err != nil {
return nil, err
Expand Down
9 changes: 9 additions & 0 deletions rpc/sigpipe.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// +build !darwin

package rpc

import "net"

func DisableSigPipe(c net.Conn) error {
return nil
}
17 changes: 17 additions & 0 deletions rpc/sigpipe_bsd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//+build darwin

package rpc

import (
"net"
"reflect"
"syscall"
)

func DisableSigPipe(c net.Conn) error {
// Disable SIGPIPE on this connection since we currently need to do this manually for iOS
// to prevent the signal from crashing iOS apps.
// See: https://github.com/golang/go/issues/17393
fd := int(reflect.ValueOf(c).Elem().FieldByName("fd").Elem().FieldByName("sysfd").Int())
return syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_NOSIGPIPE, 1)
}

0 comments on commit ed07556

Please sign in to comment.