Source File
packets.go
Belonging Package
github.com/pkg/sftp/internal/encoding/ssh/filexfer
package sshfximport ()// smallBufferSize is an initial allocation minimal capacity.const smallBufferSize = 64// RawPacket implements the general packet format from draft-ietf-secsh-filexfer-02//// RawPacket is intended for use in clients receiving responses,// where a response will be expected to be of a limited number of types,// and unmarshaling unknown/unexpected response packets is unnecessary.//// For servers expecting to receive arbitrary request packet types,// use RequestPacket.//// Defined in https://filezilla-project.org/specs/draft-ietf-secsh-filexfer-02.txt#section-3type RawPacket struct {PacketType PacketTypeRequestID uint32Data Buffer}// Type returns the Type field defining the SSH_FXP_xy type for this packet.func ( *RawPacket) () PacketType {return .PacketType}// Reset clears the pointers and reference-semantic variables of RawPacket,// releasing underlying resources, and making them and the RawPacket suitable to be reused,// so long as no other references have been kept.func ( *RawPacket) () {.Data = Buffer{}}// MarshalPacket returns p as a two-part binary encoding of p.//// The internal p.RequestID is overridden by the reqid argument.func ( *RawPacket) ( uint32, []byte) (, []byte, error) {:= NewBuffer()if .Cap() < 9 {= NewMarshalBuffer(0)}.StartPacket(.PacketType, )return .Packet(.Data.Bytes())}// MarshalBinary returns p as the binary encoding of p.//// This is a convenience implementation primarily intended for tests,// because it is inefficient with allocations.func ( *RawPacket) () ([]byte, error) {return ComposePacket(.MarshalPacket(.RequestID, nil))}// UnmarshalFrom decodes a RawPacket from the given Buffer into p.//// The Data field will alias the passed in Buffer,// so the buffer passed in should not be reused before RawPacket.Reset().func ( *RawPacket) ( *Buffer) error {* = RawPacket{PacketType: PacketType(.ConsumeUint8()),RequestID: .ConsumeUint32(),}.Data = *return .Err}// UnmarshalBinary decodes a full raw packet out of the given data.// It is assumed that the uint32(length) has already been consumed to receive the data.//// This is a convenience implementation primarily intended for tests,// because this must clone the given data byte slice,// as Data is not allowed to alias any part of the data byte slice.func ( *RawPacket) ( []byte) error {:= make([]byte, len()):= copy(, )return .UnmarshalFrom(NewBuffer([:]))}// readPacket reads a uint32 length-prefixed binary data packet from r.// using the given byte slice as a backing array.//// If the packet length read from r is bigger than maxPacketLength,// or greater than math.MaxInt32 on a 32-bit implementation,// then a `ErrLongPacket` error will be returned.//// If the given byte slice is insufficient to hold the packet,// then it will be extended to fill the packet size.func readPacket( io.Reader, []byte, uint32) ([]byte, error) {if cap() < 4 {// We will need allocate our own buffer just for reading the packet length.// However, we don’t really want to allocate an extremely narrow buffer (4-bytes),// and cause unnecessary allocation churn from both length reads and small packet reads,// so we use smallBufferSize from the bytes package as a reasonable guess.// But if callers really do want to force narrow throw-away allocation of every packet body,// they can do so with a buffer of capacity 4.= make([]byte, smallBufferSize)}if , := io.ReadFull(, [:4]); != nil {return nil,}:= unmarshalUint32()if int() < 5 {// Must have at least uint8(type) and uint32(request-id)if int() < 0 {// Only possible when strconv.IntSize == 32,// the packet length is longer than math.MaxInt32,// and thus longer than any possible slice.return nil, ErrLongPacket}return nil, ErrShortPacket}if > {return nil, ErrLongPacket}if int() > cap() {// We know int(length) must be positive, because of tests above.= make([]byte, )}, := io.ReadFull(, [:])return [:],}// ReadFrom provides a simple functional packet reader,// using the given byte slice as a backing array.//// To protect against potential denial of service attacks,// if the read packet length is longer than maxPacketLength,// then no packet data will be read, and ErrLongPacket will be returned.// (On 32-bit int architectures, all packets >= 2^31 in length// will return ErrLongPacket regardless of maxPacketLength.)//// If the read packet length is longer than cap(b),// then a throw-away slice will allocated to meet the exact packet length.// This can be used to limit the length of reused buffers,// while still allowing reception of occasional large packets.//// The Data field may alias the passed in byte slice,// so the byte slice passed in should not be reused before RawPacket.Reset().func ( *RawPacket) ( io.Reader, []byte, uint32) error {, := readPacket(, , )if != nil {return}return .UnmarshalFrom(NewBuffer())}// RequestPacket implements the general packet format from draft-ietf-secsh-filexfer-02// but also automatically decode/encodes valid request packets (2 < type < 100 || type == 200).//// RequestPacket is intended for use in servers receiving requests,// where any arbitrary request may be received, and so decoding them automatically// is useful.//// For clients expecting to receive specific response packet types,// where automatic unmarshaling of the packet body does not make sense,// use RawPacket.//// Defined in https://filezilla-project.org/specs/draft-ietf-secsh-filexfer-02.txt#section-3type RequestPacket struct {RequestID uint32Request Packet}// Type returns the SSH_FXP_xy value associated with the underlying packet.func ( *RequestPacket) () PacketType {return .Request.Type()}// Reset clears the pointers and reference-semantic variables in RequestPacket,// releasing underlying resources, and making them and the RequestPacket suitable to be reused,// so long as no other references have been kept.func ( *RequestPacket) () {.Request = nil}// MarshalPacket returns p as a two-part binary encoding of p.//// The internal p.RequestID is overridden by the reqid argument.func ( *RequestPacket) ( uint32, []byte) (, []byte, error) {if .Request == nil {return nil, nil, errors.New("empty request packet")}return .Request.MarshalPacket(, )}// MarshalBinary returns p as the binary encoding of p.//// This is a convenience implementation primarily intended for tests,// because it is inefficient with allocations.func ( *RequestPacket) () ([]byte, error) {return ComposePacket(.MarshalPacket(.RequestID, nil))}// UnmarshalFrom decodes a RequestPacket from the given Buffer into p.//// The Request field may alias the passed in Buffer, (e.g. SSH_FXP_WRITE),// so the buffer passed in should not be reused before RequestPacket.Reset().func ( *RequestPacket) ( *Buffer) error {:= PacketType(.ConsumeUint8())if .Err != nil {return .Err}, := newPacketFromType()if != nil {return}* = RequestPacket{RequestID: .ConsumeUint32(),Request: ,}return .Request.UnmarshalPacketBody()}// UnmarshalBinary decodes a full request packet out of the given data.// It is assumed that the uint32(length) has already been consumed to receive the data.//// This is a convenience implementation primarily intended for tests,// because this must clone the given data byte slice,// as Request is not allowed to alias any part of the data byte slice.func ( *RequestPacket) ( []byte) error {:= make([]byte, len()):= copy(, )return .UnmarshalFrom(NewBuffer([:]))}// ReadFrom provides a simple functional packet reader,// using the given byte slice as a backing array.//// To protect against potential denial of service attacks,// if the read packet length is longer than maxPacketLength,// then no packet data will be read, and ErrLongPacket will be returned.// (On 32-bit int architectures, all packets >= 2^31 in length// will return ErrLongPacket regardless of maxPacketLength.)//// If the read packet length is longer than cap(b),// then a throw-away slice will allocated to meet the exact packet length.// This can be used to limit the length of reused buffers,// while still allowing reception of occasional large packets.//// The Request field may alias the passed in byte slice,// so the byte slice passed in should not be reused before RawPacket.Reset().func ( *RequestPacket) ( io.Reader, []byte, uint32) error {, := readPacket(, , )if != nil {return}return .UnmarshalFrom(NewBuffer())}
![]() |
The pages are generated with Golds v0.6.7. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |