blob: fb3d0c025e3a58ce61336c01884ba4b58f12d69e [file] [log] [blame]
// Copyright 2015 The LUCI Authors. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.
package streamserver
import (
"net"
"golang.org/x/net/context"
"github.com/luci/luci-go/common/errors"
log "github.com/luci/luci-go/common/logging"
"github.com/luci/luci-go/logdog/client/butlerlib/streamclient"
"github.com/Microsoft/go-winio"
)
// maxWindowsNamedPipeLength is the maximum length of a Windows named pipe.
const maxWindowsNamedPipeLength = 256
// NewNamedPipeServer instantiates a new Windows named pipe server instance.
func NewNamedPipeServer(ctx context.Context, name string) (StreamServer, error) {
switch l := len(name); {
case l == 0:
return nil, errors.New("cannot have empty name")
case l > maxWindowsNamedPipeLength:
return nil, errors.Reason("name exceeds maximum length %(max)d").
D("name", name).
D("max", maxWindowsNamedPipeLength).
Err()
}
ctx = log.SetField(ctx, "name", name)
return &listenerStreamServer{
Context: ctx,
gen: func() (net.Listener, string, error) {
address := "net.pipe:" + name
pipePath := streamclient.LocalNamedPipePath(name)
log.Fields{
"addr": address,
"pipePath": pipePath,
}.Debugf(ctx, "Creating Windows server socket Listener.")
l, err := winio.ListenPipe(pipePath, nil)
if err != nil {
return nil, "", errors.Annotate(err).Reason("failed to listen on named pipe").Err()
}
return l, address, nil
},
}, nil
}