github.com/gdamore/mangos@v1.4.0/connipc_windows.go (about) 1 // +build windows 2 3 // Copyright 2018 The Mangos Authors 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use file except in compliance with the License. 7 // You may obtain a copy of the license at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 package mangos 18 19 import ( 20 "encoding/binary" 21 "io" 22 "net" 23 ) 24 25 // NewConnPipeIPC allocates a new Pipe using the IPC exchange protocol. 26 func NewConnPipeIPC(c net.Conn, sock Socket, props ...interface{}) (Pipe, error) { 27 p := &connipc{conn: conn{c: c, proto: sock.GetProtocol(), sock: sock}} 28 29 if err := p.handshake(props); err != nil { 30 return nil, err 31 } 32 33 return p, nil 34 } 35 36 func (p *connipc) Send(msg *Message) error { 37 38 l := uint64(len(msg.Header) + len(msg.Body)) 39 var err error 40 41 // On Windows, we have to put everything into a contiguous buffer. 42 // This is to workaround bugs in legacy libnanomsg. Eventually we 43 // might do away with this logic, but only when legacy libnanomsg 44 // has been fixed. This puts some pressure on the gc too, which 45 // makes me pretty sad. 46 47 // send length header 48 buf := make([]byte, 9, 9+l) 49 buf[0] = 1 50 binary.BigEndian.PutUint64(buf[1:], l) 51 buf = append(buf, msg.Header...) 52 buf = append(buf, msg.Body...) 53 54 if _, err = p.c.Write(buf[:]); err != nil { 55 return err 56 } 57 msg.Free() 58 return nil 59 } 60 61 func (p *connipc) Recv() (*Message, error) { 62 63 var sz int64 64 var err error 65 var msg *Message 66 var one [1]byte 67 68 if _, err = p.c.Read(one[:]); err != nil { 69 return nil, err 70 } 71 if err = binary.Read(p.c, binary.BigEndian, &sz); err != nil { 72 return nil, err 73 } 74 75 // Limit messages to the maximum receive value, if not 76 // unlimited. This avoids a potential denaial of service. 77 if sz < 0 || (p.maxrx > 0 && sz > p.maxrx) { 78 return nil, ErrTooLong 79 } 80 msg = NewMessage(int(sz)) 81 msg.Body = msg.Body[0:sz] 82 if _, err = io.ReadFull(p.c, msg.Body); err != nil { 83 msg.Free() 84 return nil, err 85 } 86 return msg, nil 87 }