Documentation ¶
Overview ¶
Package kcp is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/transport/internet/kcp/config.proto
It has these top-level messages:
MTU TTI UplinkCapacity DownlinkCapacity WriteBuffer ReadBuffer Config
Package kcp - A Fast and Reliable ARQ Protocol ¶
Acknowledgement:
skywind3000@github for inventing the KCP protocol xtaci@github for translating to Golang
Index ¶
- Constants
- Variables
- func AllocateBuffer() *alloc.Buffer
- func DialKCP(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (internet.Connection, error)
- func ListenKCP(address v2net.Address, port v2net.Port, options internet.ListenOptions) (internet.Listener, error)
- func NewSimpleAuthenticator() internet.Authenticator
- type AckList
- type AckSegment
- type AuthenticationWriter
- type Buffer
- type BufferedSegmentWriter
- type CmdOnlySegment
- type Command
- type Config
- func (*Config) Descriptor() ([]byte, []int)
- func (this *Config) GetAuthenticator() (internet.Authenticator, error)
- func (m *Config) GetDownlinkCapacity() *DownlinkCapacity
- func (m *Config) GetHeaderConfig() *v2ray_core_transport_internet.AuthenticatorConfig
- func (m *Config) GetMtu() *MTU
- func (m *Config) GetReadBuffer() *ReadBuffer
- func (this *Config) GetReceivingBufferSize() uint32
- func (this *Config) GetReceivingInFlightSize() uint32
- func (this *Config) GetSendingBufferSize() uint32
- func (this *Config) GetSendingInFlightSize() uint32
- func (m *Config) GetTti() *TTI
- func (m *Config) GetUplinkCapacity() *UplinkCapacity
- func (m *Config) GetWriteBuffer() *WriteBuffer
- func (*Config) ProtoMessage()
- func (m *Config) Reset()
- func (m *Config) String() string
- type Connection
- func (this *Connection) Close() error
- func (this *Connection) Elapsed() uint32
- func (this *Connection) FetchInputFrom(conn io.Reader)
- func (this *Connection) HandleOption(opt SegmentOption)
- func (this *Connection) Input(data []byte) int
- func (this *Connection) LocalAddr() net.Addr
- func (this *Connection) OnPeerClosed()
- func (this *Connection) Read(b []byte) (int, error)
- func (this *Connection) RemoteAddr() net.Addr
- func (this *Connection) Reusable() bool
- func (this *Connection) SetDeadline(t time.Time) error
- func (this *Connection) SetReadDeadline(t time.Time) error
- func (this *Connection) SetReusable(b bool)
- func (this *Connection) SetState(state State)
- func (this *Connection) SetWriteDeadline(t time.Time) error
- func (this *Connection) State() State
- func (this *Connection) Terminate()
- func (this *Connection) Write(b []byte) (int, error)
- type DataSegment
- type DownlinkCapacity
- type Listener
- func (this *Listener) Accept() (internet.Connection, error)
- func (this *Listener) ActiveConnections() int
- func (this *Listener) Addr() net.Addr
- func (this *Listener) Close() error
- func (this *Listener) OnReceive(payload *alloc.Buffer, session *proxy.SessionInfo)
- func (this *Listener) Remove(dest string)
- type MTU
- type ReadBuffer
- type ReceivingWindow
- func (this *ReceivingWindow) Advance()
- func (this *ReceivingWindow) Position(idx uint32) uint32
- func (this *ReceivingWindow) Remove(idx uint32) *DataSegment
- func (this *ReceivingWindow) RemoveFirst() *DataSegment
- func (this *ReceivingWindow) Set(idx uint32, value *DataSegment) bool
- func (this *ReceivingWindow) Size() uint32
- type ReceivingWorker
- func (this *ReceivingWorker) CloseRead()
- func (this *ReceivingWorker) Flush(current uint32)
- func (this *ReceivingWorker) ProcessSegment(seg *DataSegment)
- func (this *ReceivingWorker) ProcessSendingNext(number uint32)
- func (this *ReceivingWorker) Read(b []byte) int
- func (this *ReceivingWorker) Write(seg Segment)
- type RoundTripInfo
- type Segment
- type SegmentOption
- type SegmentWriter
- type SendingWindow
- func (this *SendingWindow) Clear(una uint32)
- func (this *SendingWindow) First() *DataSegment
- func (this *SendingWindow) Flush(current uint32, resend uint32, rto uint32, maxInFlightSize uint32)
- func (this *SendingWindow) HandleFastAck(number uint32)
- func (this *SendingWindow) IsEmpty() bool
- func (this *SendingWindow) IsFull() bool
- func (this *SendingWindow) Len() int
- func (this *SendingWindow) Push(seg *DataSegment)
- func (this *SendingWindow) Remove(idx uint32)
- func (this *SendingWindow) Size() uint32
- type SendingWorker
- func (this *SendingWorker) CloseWrite()
- func (this *SendingWorker) FindFirstUnacknowledged()
- func (this *SendingWorker) Flush(current uint32)
- func (this *SendingWorker) IsEmpty() bool
- func (this *SendingWorker) OnPacketLoss(lossRate uint32)
- func (this *SendingWorker) ProcessAck(number uint32)
- func (this *SendingWorker) ProcessReceivingNext(nextNumber uint32)
- func (this *SendingWorker) ProcessReceivingNextWithoutLock(nextNumber uint32)
- func (this *SendingWorker) ProcessSegment(current uint32, seg *AckSegment)
- func (this *SendingWorker) Push(b []byte) int
- func (this *SendingWorker) Write(seg Segment)
- type SimpleAuthenticator
- type State
- type TTI
- type UplinkCapacity
- type WriteBuffer
- type Writer
Constants ¶
const ( NumDistro = 5 DistroSize = 1600 )
const (
DataSegmentOverhead = 18
)
Variables ¶
Functions ¶
func AllocateBuffer ¶ added in v1.23.1
func DialKCP ¶
func DialKCP(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (internet.Connection, error)
func NewSimpleAuthenticator ¶
func NewSimpleAuthenticator() internet.Authenticator
Types ¶
type AckList ¶ added in v1.18.1
type AckList struct {
// contains filtered or unexported fields
}
func NewAckList ¶ added in v1.18.1
func NewAckList(writer SegmentWriter) *AckList
type AckSegment ¶ added in v1.18.1
type AckSegment struct { Conv uint16 Option SegmentOption ReceivingWindow uint32 ReceivingNext uint32 Timestamp uint32 Count byte NumberList []uint32 }
func NewAckSegment ¶ added in v1.19.1
func NewAckSegment() *AckSegment
func (*AckSegment) ByteSize ¶ added in v1.18.1
func (this *AckSegment) ByteSize() int
func (*AckSegment) Bytes ¶ added in v1.18.1
func (this *AckSegment) Bytes(b []byte) []byte
func (*AckSegment) IsFull ¶ added in v1.19.1
func (this *AckSegment) IsFull() bool
func (*AckSegment) PutNumber ¶ added in v1.19.1
func (this *AckSegment) PutNumber(number uint32)
func (*AckSegment) PutTimestamp ¶ added in v1.23.1
func (this *AckSegment) PutTimestamp(timestamp uint32)
func (*AckSegment) Release ¶ added in v1.18.1
func (this *AckSegment) Release()
type AuthenticationWriter ¶ added in v1.18.1
type AuthenticationWriter struct { Authenticator internet.Authenticator Writer io.Writer Config *Config }
func (*AuthenticationWriter) Mtu ¶ added in v1.18.1
func (this *AuthenticationWriter) Mtu() uint32
func (*AuthenticationWriter) Release ¶ added in v1.18.1
func (this *AuthenticationWriter) Release()
type Buffer ¶ added in v1.23.1
func (*Buffer) ReleaseBuffer ¶ added in v1.23.1
func (this *Buffer) ReleaseBuffer()
type BufferedSegmentWriter ¶ added in v1.18.1
func NewSegmentWriter ¶ added in v1.18.1
func NewSegmentWriter(writer *AuthenticationWriter) *BufferedSegmentWriter
func (*BufferedSegmentWriter) Flush ¶ added in v1.18.1
func (this *BufferedSegmentWriter) Flush()
func (*BufferedSegmentWriter) FlushWithoutLock ¶ added in v1.18.1
func (this *BufferedSegmentWriter) FlushWithoutLock()
func (*BufferedSegmentWriter) Write ¶ added in v1.18.1
func (this *BufferedSegmentWriter) Write(seg Segment)
type CmdOnlySegment ¶ added in v1.18.1
type CmdOnlySegment struct { Conv uint16 Command Command Option SegmentOption SendingNext uint32 ReceivinNext uint32 PeerRTO uint32 }
func NewCmdOnlySegment ¶ added in v1.19.1
func NewCmdOnlySegment() *CmdOnlySegment
func (*CmdOnlySegment) ByteSize ¶ added in v1.18.1
func (this *CmdOnlySegment) ByteSize() int
func (*CmdOnlySegment) Bytes ¶ added in v1.18.1
func (this *CmdOnlySegment) Bytes(b []byte) []byte
func (*CmdOnlySegment) Release ¶ added in v1.18.1
func (this *CmdOnlySegment) Release()
type Config ¶
type Config struct { Mtu *MTU `protobuf:"bytes,1,opt,name=mtu" json:"mtu,omitempty"` Tti *TTI `protobuf:"bytes,2,opt,name=tti" json:"tti,omitempty"` UplinkCapacity *UplinkCapacity `protobuf:"bytes,3,opt,name=uplink_capacity,json=uplinkCapacity" json:"uplink_capacity,omitempty"` DownlinkCapacity *DownlinkCapacity `protobuf:"bytes,4,opt,name=downlink_capacity,json=downlinkCapacity" json:"downlink_capacity,omitempty"` Congestion bool `protobuf:"varint,5,opt,name=congestion" json:"congestion,omitempty"` WriteBuffer *WriteBuffer `protobuf:"bytes,6,opt,name=write_buffer,json=writeBuffer" json:"write_buffer,omitempty"` ReadBuffer *ReadBuffer `protobuf:"bytes,7,opt,name=read_buffer,json=readBuffer" json:"read_buffer,omitempty"` HeaderConfig *v2ray_core_transport_internet.AuthenticatorConfig `protobuf:"bytes,8,opt,name=header_config,json=headerConfig" json:"header_config,omitempty"` }
func (*Config) Descriptor ¶
func (*Config) GetAuthenticator ¶ added in v1.23.1
func (this *Config) GetAuthenticator() (internet.Authenticator, error)
func (*Config) GetDownlinkCapacity ¶
func (m *Config) GetDownlinkCapacity() *DownlinkCapacity
func (*Config) GetHeaderConfig ¶
func (m *Config) GetHeaderConfig() *v2ray_core_transport_internet.AuthenticatorConfig
func (*Config) GetReadBuffer ¶
func (m *Config) GetReadBuffer() *ReadBuffer
func (*Config) GetReceivingBufferSize ¶
func (*Config) GetReceivingInFlightSize ¶
func (*Config) GetSendingBufferSize ¶
func (*Config) GetSendingInFlightSize ¶ added in v1.18.2
func (*Config) GetUplinkCapacity ¶
func (m *Config) GetUplinkCapacity() *UplinkCapacity
func (*Config) GetWriteBuffer ¶
func (m *Config) GetWriteBuffer() *WriteBuffer
func (*Config) ProtoMessage ¶
func (*Config) ProtoMessage()
type Connection ¶
type Connection struct { Config *Config // contains filtered or unexported fields }
Connection is a KCP connection over UDP.
func NewConnection ¶
func NewConnection(conv uint16, writerCloser io.WriteCloser, local *net.UDPAddr, remote *net.UDPAddr, block internet.Authenticator, config *Config) *Connection
NewConnection create a new KCP connection between local and remote.
func (*Connection) Elapsed ¶
func (this *Connection) Elapsed() uint32
func (*Connection) FetchInputFrom ¶
func (this *Connection) FetchInputFrom(conn io.Reader)
func (*Connection) HandleOption ¶ added in v1.19.1
func (this *Connection) HandleOption(opt SegmentOption)
func (*Connection) Input ¶ added in v1.19.1
func (this *Connection) Input(data []byte) int
Input when you received a low level packet (eg. UDP packet), call it
func (*Connection) LocalAddr ¶
func (this *Connection) LocalAddr() net.Addr
LocalAddr returns the local network address. The Addr returned is shared by all invocations of LocalAddr, so do not modify it.
func (*Connection) OnPeerClosed ¶ added in v1.19.1
func (this *Connection) OnPeerClosed()
func (*Connection) Read ¶
func (this *Connection) Read(b []byte) (int, error)
Read implements the Conn Read method.
func (*Connection) RemoteAddr ¶
func (this *Connection) RemoteAddr() net.Addr
RemoteAddr returns the remote network address. The Addr returned is shared by all invocations of RemoteAddr, so do not modify it.
func (*Connection) Reusable ¶
func (this *Connection) Reusable() bool
func (*Connection) SetDeadline ¶
func (this *Connection) SetDeadline(t time.Time) error
SetDeadline sets the deadline associated with the listener. A zero time value disables the deadline.
func (*Connection) SetReadDeadline ¶
func (this *Connection) SetReadDeadline(t time.Time) error
SetReadDeadline implements the Conn SetReadDeadline method.
func (*Connection) SetReusable ¶
func (this *Connection) SetReusable(b bool)
func (*Connection) SetState ¶ added in v1.19.1
func (this *Connection) SetState(state State)
func (*Connection) SetWriteDeadline ¶
func (this *Connection) SetWriteDeadline(t time.Time) error
SetWriteDeadline implements the Conn SetWriteDeadline method.
func (*Connection) State ¶ added in v1.19.1
func (this *Connection) State() State
func (*Connection) Terminate ¶
func (this *Connection) Terminate()
type DataSegment ¶ added in v1.18.1
type DataSegment struct { Conv uint16 Option SegmentOption Timestamp uint32 Number uint32 SendingNext uint32 Data *alloc.Buffer // contains filtered or unexported fields }
func NewDataSegment ¶ added in v1.19.1
func NewDataSegment() *DataSegment
func (*DataSegment) ByteSize ¶ added in v1.18.1
func (this *DataSegment) ByteSize() int
func (*DataSegment) Bytes ¶ added in v1.18.1
func (this *DataSegment) Bytes(b []byte) []byte
func (*DataSegment) Release ¶ added in v1.18.1
func (this *DataSegment) Release()
type DownlinkCapacity ¶
type DownlinkCapacity struct {
Value uint32 `protobuf:"varint,1,opt,name=value" json:"value,omitempty"`
}
Downlink capacity, in MB.
func (*DownlinkCapacity) Descriptor ¶
func (*DownlinkCapacity) Descriptor() ([]byte, []int)
func (*DownlinkCapacity) GetValue ¶
func (this *DownlinkCapacity) GetValue() uint32
func (*DownlinkCapacity) ProtoMessage ¶
func (*DownlinkCapacity) ProtoMessage()
func (*DownlinkCapacity) Reset ¶
func (m *DownlinkCapacity) Reset()
func (*DownlinkCapacity) String ¶
func (m *DownlinkCapacity) String() string
type Listener ¶
Listener defines a server listening for connections
func NewListener ¶
func (*Listener) Accept ¶
func (this *Listener) Accept() (internet.Connection, error)
Accept implements the Accept method in the Listener interface; it waits for the next call and returns a generic Conn.
func (*Listener) ActiveConnections ¶ added in v1.19.2
func (*Listener) Addr ¶
Addr returns the listener's network address, The Addr returned is shared by all invocations of Addr, so do not modify it.
func (*Listener) Close ¶
Close stops listening on the UDP address. Already Accepted connections are not closed.
type MTU ¶
type MTU struct {
Value uint32 `protobuf:"varint,1,opt,name=value" json:"value,omitempty"`
}
Maximum Transmission Unit, in bytes.
func (*MTU) Descriptor ¶
func (*MTU) ProtoMessage ¶
func (*MTU) ProtoMessage()
type ReadBuffer ¶
type ReadBuffer struct { // Buffer size in bytes. Size uint32 `protobuf:"varint,1,opt,name=size" json:"size,omitempty"` }
func (*ReadBuffer) Descriptor ¶
func (*ReadBuffer) Descriptor() ([]byte, []int)
func (*ReadBuffer) GetSize ¶
func (this *ReadBuffer) GetSize() uint32
func (*ReadBuffer) ProtoMessage ¶
func (*ReadBuffer) ProtoMessage()
func (*ReadBuffer) Reset ¶
func (m *ReadBuffer) Reset()
func (*ReadBuffer) String ¶
func (m *ReadBuffer) String() string
type ReceivingWindow ¶ added in v1.17.3
type ReceivingWindow struct {
// contains filtered or unexported fields
}
func NewReceivingWindow ¶ added in v1.17.3
func NewReceivingWindow(size uint32) *ReceivingWindow
func (*ReceivingWindow) Advance ¶ added in v1.17.3
func (this *ReceivingWindow) Advance()
func (*ReceivingWindow) Position ¶ added in v1.17.3
func (this *ReceivingWindow) Position(idx uint32) uint32
func (*ReceivingWindow) Remove ¶ added in v1.17.3
func (this *ReceivingWindow) Remove(idx uint32) *DataSegment
func (*ReceivingWindow) RemoveFirst ¶ added in v1.17.3
func (this *ReceivingWindow) RemoveFirst() *DataSegment
func (*ReceivingWindow) Set ¶ added in v1.17.3
func (this *ReceivingWindow) Set(idx uint32, value *DataSegment) bool
func (*ReceivingWindow) Size ¶ added in v1.17.3
func (this *ReceivingWindow) Size() uint32
type ReceivingWorker ¶ added in v1.18.1
func NewReceivingWorker ¶ added in v1.18.1
func NewReceivingWorker(kcp *Connection) *ReceivingWorker
func (*ReceivingWorker) CloseRead ¶ added in v1.18.1
func (this *ReceivingWorker) CloseRead()
func (*ReceivingWorker) Flush ¶ added in v1.18.1
func (this *ReceivingWorker) Flush(current uint32)
func (*ReceivingWorker) ProcessSegment ¶ added in v1.18.1
func (this *ReceivingWorker) ProcessSegment(seg *DataSegment)
func (*ReceivingWorker) ProcessSendingNext ¶ added in v1.18.1
func (this *ReceivingWorker) ProcessSendingNext(number uint32)
func (*ReceivingWorker) Read ¶ added in v1.18.1
func (this *ReceivingWorker) Read(b []byte) int
func (*ReceivingWorker) Write ¶ added in v1.18.1
func (this *ReceivingWorker) Write(seg Segment)
type RoundTripInfo ¶ added in v1.23.1
func (*RoundTripInfo) SmoothedTime ¶ added in v1.23.1
func (this *RoundTripInfo) SmoothedTime() uint32
func (*RoundTripInfo) Timeout ¶ added in v1.23.1
func (this *RoundTripInfo) Timeout() uint32
func (*RoundTripInfo) Update ¶ added in v1.23.1
func (this *RoundTripInfo) Update(rtt uint32, current uint32)
func (*RoundTripInfo) UpdatePeerRTO ¶ added in v1.23.1
func (this *RoundTripInfo) UpdatePeerRTO(rto uint32, current uint32)
type Segment ¶
type Segment interface { common.Releasable ByteSize() int Bytes([]byte) []byte }
func ReadSegment ¶ added in v1.18.1
type SegmentOption ¶ added in v1.18.1
type SegmentOption byte
const (
SegmentOptionClose SegmentOption = 1
)
type SegmentWriter ¶ added in v1.18.1
type SegmentWriter interface {
Write(seg Segment)
}
type SendingWindow ¶ added in v1.18.1
type SendingWindow struct {
// contains filtered or unexported fields
}
func NewSendingWindow ¶ added in v1.18.1
func NewSendingWindow(size uint32, writer SegmentWriter, onPacketLoss func(uint32)) *SendingWindow
func (*SendingWindow) Clear ¶ added in v1.18.1
func (this *SendingWindow) Clear(una uint32)
func (*SendingWindow) First ¶ added in v1.18.1
func (this *SendingWindow) First() *DataSegment
func (*SendingWindow) Flush ¶ added in v1.18.1
func (this *SendingWindow) Flush(current uint32, resend uint32, rto uint32, maxInFlightSize uint32)
func (*SendingWindow) HandleFastAck ¶ added in v1.18.1
func (this *SendingWindow) HandleFastAck(number uint32)
func (*SendingWindow) IsEmpty ¶ added in v1.19.2
func (this *SendingWindow) IsEmpty() bool
func (*SendingWindow) IsFull ¶ added in v1.18.2
func (this *SendingWindow) IsFull() bool
func (*SendingWindow) Len ¶ added in v1.18.1
func (this *SendingWindow) Len() int
func (*SendingWindow) Push ¶ added in v1.18.1
func (this *SendingWindow) Push(seg *DataSegment)
func (*SendingWindow) Remove ¶ added in v1.18.1
func (this *SendingWindow) Remove(idx uint32)
func (*SendingWindow) Size ¶ added in v1.18.2
func (this *SendingWindow) Size() uint32
type SendingWorker ¶ added in v1.18.1
func NewSendingWorker ¶ added in v1.18.1
func NewSendingWorker(kcp *Connection) *SendingWorker
func (*SendingWorker) CloseWrite ¶ added in v1.18.1
func (this *SendingWorker) CloseWrite()
func (*SendingWorker) FindFirstUnacknowledged ¶ added in v1.18.1
func (this *SendingWorker) FindFirstUnacknowledged()
Private: Visible for testing.
func (*SendingWorker) Flush ¶ added in v1.18.1
func (this *SendingWorker) Flush(current uint32)
func (*SendingWorker) IsEmpty ¶ added in v1.19.2
func (this *SendingWorker) IsEmpty() bool
func (*SendingWorker) OnPacketLoss ¶ added in v1.18.1
func (this *SendingWorker) OnPacketLoss(lossRate uint32)
func (*SendingWorker) ProcessAck ¶ added in v1.18.1
func (this *SendingWorker) ProcessAck(number uint32)
Private: Visible for testing.
func (*SendingWorker) ProcessReceivingNext ¶ added in v1.18.1
func (this *SendingWorker) ProcessReceivingNext(nextNumber uint32)
func (*SendingWorker) ProcessReceivingNextWithoutLock ¶ added in v1.19.1
func (this *SendingWorker) ProcessReceivingNextWithoutLock(nextNumber uint32)
func (*SendingWorker) ProcessSegment ¶ added in v1.18.2
func (this *SendingWorker) ProcessSegment(current uint32, seg *AckSegment)
func (*SendingWorker) Push ¶ added in v1.18.1
func (this *SendingWorker) Push(b []byte) int
func (*SendingWorker) Write ¶ added in v1.18.1
func (this *SendingWorker) Write(seg Segment)
Private: Visible for testing.
type SimpleAuthenticator ¶
type SimpleAuthenticator struct{}
func (*SimpleAuthenticator) Overhead ¶ added in v1.23.1
func (this *SimpleAuthenticator) Overhead() int
func (*SimpleAuthenticator) Seal ¶
func (this *SimpleAuthenticator) Seal(buffer *alloc.Buffer)
type TTI ¶
type TTI struct {
Value uint32 `protobuf:"varint,1,opt,name=value" json:"value,omitempty"`
}
Transmission Time Interview, in milli-sec.
func (*TTI) Descriptor ¶
func (*TTI) ProtoMessage ¶
func (*TTI) ProtoMessage()
type UplinkCapacity ¶
type UplinkCapacity struct {
Value uint32 `protobuf:"varint,1,opt,name=value" json:"value,omitempty"`
}
Uplink capacity, in MB.
func (*UplinkCapacity) Descriptor ¶
func (*UplinkCapacity) Descriptor() ([]byte, []int)
func (*UplinkCapacity) GetValue ¶
func (this *UplinkCapacity) GetValue() uint32
func (*UplinkCapacity) ProtoMessage ¶
func (*UplinkCapacity) ProtoMessage()
func (*UplinkCapacity) Reset ¶
func (m *UplinkCapacity) Reset()
func (*UplinkCapacity) String ¶
func (m *UplinkCapacity) String() string
type WriteBuffer ¶
type WriteBuffer struct { // Buffer size in bytes. Size uint32 `protobuf:"varint,1,opt,name=size" json:"size,omitempty"` }
func (*WriteBuffer) Descriptor ¶
func (*WriteBuffer) Descriptor() ([]byte, []int)
func (*WriteBuffer) GetSize ¶
func (this *WriteBuffer) GetSize() uint32
func (*WriteBuffer) ProtoMessage ¶
func (*WriteBuffer) ProtoMessage()
func (*WriteBuffer) Reset ¶
func (m *WriteBuffer) Reset()
func (*WriteBuffer) String ¶
func (m *WriteBuffer) String() string