208 default:
return "INVALID";
221 DBGC ( tcp,
"TCP %p transitioned from %s to %s\n", tcp,
236 DBGC2 ( tcp,
" RST" );
238 DBGC2 ( tcp,
" SYN" );
240 DBGC2 ( tcp,
" PSH" );
242 DBGC2 ( tcp,
" FIN" );
244 DBGC2 ( tcp,
" ACK" );
283 tcp =
zalloc (
sizeof ( *tcp ) );
286 DBGC ( tcp,
"TCP %p allocated\n", tcp );
304 DBGC ( tcp,
"TCP %p has no route to %s\n",
315 DBGC ( tcp,
"TCP %p could not bind: %s\n",
392 DBGC ( tcp,
"TCP %p connection deleted\n", tcp );
483 tcpqhdr = iobuf->
data;
490 right = tcpqhdr->
nxt;
500 return ( right - left );
512 unsigned int old = 0;
513 unsigned int new = 0;
539 for ( i = 0 ; i < new ; i++ ) {
540 if ( sack[i].
left == sack[
new].
left ) {
577 if ( frag_len > max_len )
620 unsigned int sack_count;
633 if ( timer_running ( &tcp->
timer ) )
667 DBGC ( tcp,
"TCP %p could not allocate iobuf for %08x..%08x " 682 if ( max_rcv_win > max_representable_win )
683 max_rcv_win = max_representable_win;
684 max_rcv_win &= ~0x03;
685 if ( tcp->
rcv_win < max_rcv_win )
689 payload = iobuf->
data;
691 mssopt =
iob_push ( iobuf,
sizeof ( *mssopt ) );
693 mssopt->
length =
sizeof ( *mssopt );
700 spopt =
iob_push ( iobuf,
sizeof ( *spopt ) );
706 tsopt =
iob_push ( iobuf,
sizeof ( *tsopt ) );
715 ( ( sack_count =
tcp_sack ( tcp, sack_seq ) ) != 0 ) ) {
716 sack_len = ( sack_count *
sizeof ( *sack ) );
717 sackopt =
iob_push ( iobuf, (
sizeof ( *sackopt ) + sack_len ));
721 (
sizeof ( sackopt->
sackopt ) + sack_len );
722 sack = ( ( (
void * ) sackopt ) +
sizeof ( *sackopt ) );
723 for ( i = 0 ; i < sack_count ; i++, sack++ ) {
736 tcphdr->hlen = ( ( payload - iobuf->
data ) << 2 );
742 DBGC2 ( tcp,
"TCP %p TX %d->%d %08x..%08x %08x %4zd",
751 &
tcphdr->csum ) ) != 0 ) {
752 DBGC ( tcp,
"TCP %p could not transmit %08x..%08x %08x: %s\n",
789 DBGC ( tcp,
"TCP %p timer %s in %s for %08x..%08x %08x\n", tcp,
824 DBGC ( tcp,
"TCP %p sending keepalive\n", tcp );
851 DBGC ( tcp,
"TCP %p wait complete in %s for %08x..%08x %08x\n", tcp,
876 DBGC ( tcp,
"TCP %p could not allocate iobuf for RST " 877 "%08x..%08x %08x\n", tcp,
ntohl ( in_tcphdr->
ack ),
890 tcphdr->hlen = ( (
sizeof ( *tcphdr ) / 4 ) << 4 );
896 DBGC2 ( tcp,
"TCP %p TX %d->%d %08x..%08x %08x %4d",
906 DBGC ( tcp,
"TCP %p could not transmit RST %08x..%08x %08x: " 907 "%s\n", tcp,
ntohl ( in_tcphdr->
ack ),
951 const void *
data = ( ( (
void * )
tcphdr ) +
sizeof ( *tcphdr ) );
952 const void *
end = ( ( (
void * )
tcphdr ) + hlen );
963 while ( ( remaining = (
end -
data ) ) ) {
978 min =
sizeof ( *option );
999 DBGC ( tcp,
"TCP %p received unknown option %d\n",
1003 if ( remaining <
min ) {
1004 DBGC ( tcp,
"TCP %p received truncated option %d\n",
1009 DBGC ( tcp,
"TCP %p received underlength option %d\n",
1013 if (
option->length > remaining ) {
1014 DBGC ( tcp,
"TCP %p received overlength option %d\n",
1040 if ( tcp->
rcv_win > seq_len ) {
1085 DBGC ( tcp,
"TCP %p using %stimestamps, %sSACK, TX window " 1086 "x%d, RX window x%d\n", tcp,
1119 unsigned int acked_flags;
1123 DBGC ( tcp,
"TCP %p received ACK for %08x..%08x, " 1124 "sent only %08x..%08x\n", tcp, tcp->
snd_seq,
1163 if ( acked_flags ) {
1209 if ( already_rcvd >=
len ) {
1214 len -= already_rcvd;
1222 DBGC ( tcp,
"TCP %p could not deliver %08x..%08x: %s\n",
1283 DBGC ( tcp,
"TCP %p connection reset by peer\n", tcp );
1308 seq_len = (
len + (
flags ? 1 : 0 ) );
1309 nxt = (
seq + seq_len );
1321 ( seq_len == 0 ) ) {
1327 tcpqhdr =
iob_push ( iobuf,
sizeof ( *tcpqhdr ) );
1334 tcpqhdr = queued->
data;
1362 tcpqhdr = iobuf->
data;
1370 iob_pull ( iobuf,
sizeof ( *tcpqhdr ) );
1412 size_t old_xfer_window;
1420 DBG (
"TCP packet too short at %zd bytes (min %zd bytes)\n",
1426 if ( hlen <
sizeof ( *
tcphdr ) ) {
1427 DBG (
"TCP header too short at %zd bytes (min %zd bytes)\n",
1428 hlen,
sizeof ( *
tcphdr ) );
1432 if ( hlen >
iob_len ( iobuf ) ) {
1433 DBG (
"TCP header too long at %zd bytes (max %zd bytes)\n",
1441 DBG (
"TCP checksum incorrect (is %04x including checksum " 1442 "field, should be 0000)\n", csum );
1463 DBGC2 ( tcp,
"TCP %p RX %d<-%d %08x %08x..%08x %4zd",
1468 DBGC2 ( tcp,
"\n" );
1562 unsigned int discarded = 0;
1629 unsigned long start;
1630 unsigned long elapsed;
1636 DBGC ( tcp,
"TCP %p closing for shutdown\n", tcp );
#define iob_pull(iobuf, len)
#define TCP_OPTION_NOP
TCP option pad.
struct retry_timer wait
Shutdown (TIME_WAIT) timer.
#define EINVAL
Invalid argument.
An object interface operation.
#define ECONNRESET
Connection reset.
struct arbelprm_rc_send_wqe rc
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
struct tcp_timestamp_option tsopt
void intf_close(struct interface *intf, int rc)
Close an object interface.
Padded TCP window scale option (used for sending)
#define iob_put(iobuf, len)
struct list_head rx_queue
Receive queue.
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
size_t tcpip_mtu(struct sockaddr_tcpip *st_dest)
Determine maximum transmission unit.
unsigned int tcp_state
Current TCP state.
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
static void start_timer_nodelay(struct retry_timer *timer)
Start timer with no delay.
#define TCP_MASK_HLEN
Mask for TCP header length field.
static void tcp_keepalive_expired(struct retry_timer *timer, int over)
Keepalive timer expired.
struct retry_timer timer
Retransmission timer.
#define TCP_SYN_SENT
SYN_SENT.
#define TCP_LISTEN
LISTEN.
Padded TCP selective acknowledgement option (used for sending)
uint32_t snd_seq
Current sequence number.
#define list_add(new, head)
Add a new entry to the head of a list.
static int tcp_port_available(int port)
Check if local TCP port is available.
#define ref_init(refcnt, free)
Initialise a reference counter.
struct retry_timer keepalive
Keepalive timer.
struct refcnt refcnt
Reference counter.
#define TCP_RX_WINDOW_SCALE
Advertised TCP window scale.
#define iob_push(iobuf, len)
static size_t tcp_process_tx_queue(struct tcp_connection *tcp, size_t max_len, struct io_buffer *dest, int remove)
Process TCP transmit queue.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
static int tcp_xmit_reset(struct tcp_connection *tcp, struct sockaddr_tcpip *st_dest, struct tcp_header *in_tcphdr)
Send RST response to incoming packet.
void pending_put(struct pending_operation *pending)
Mark an operation as no longer pending.
#define EADDRINUSE
Address already in use.
static int tcp_rx_fin(struct tcp_connection *tcp, uint32_t seq)
Handle TCP received FIN.
TCP selective acknowledgement is enabled.
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
#define TCP_OPTION_MSS
Code for the TCP MSS option.
TCP timestamps are enabled.
static int tcp_rx_rst(struct tcp_connection *tcp, uint32_t seq)
Handle TCP received RST.
unsigned int prev_tcp_state
Previous TCP state.
struct cache_discarder tcp_discarder __cache_discarder(CACHE_NORMAL)
TCP cache discarder.
struct pending_operation pending_data
Pending operations for transmit queue.
uint8_t snd_win_scale
Send window scale.
#define PROC_DESC_ONCE(object_type, process, _step)
Define a process descriptor for a process that runs only once.
#define TCP_MSL
TCP maximum segment lifetime.
A data structure for storing profiling information.
static size_t tcp_xfer_window(struct tcp_connection *tcp)
Check data-transfer flow control window.
Uniform Resource Identifiers.
static void profile_stop(struct profiler *profiler)
Stop profiling.
static int tcp_rx(struct io_buffer *iobuf, struct net_device *netdev __unused, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest __unused, uint16_t pshdr_csum)
Process received packet.
void process_del(struct process *process)
Remove process from process list.
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
int semantics
Communication semantics (e.g.
static void tcp_shutdown(int booting __unused)
Shut down all TCP connections.
size_t xfer_window(struct interface *intf)
Check flow control window.
int tcpip_bind(struct sockaddr_tcpip *st_local, int(*available)(int port))
Bind to local TCP/IP port.
#define ECANCELED
Operation canceled.
#define TCP_OPTION_TS
Code for the TCP timestamp option.
u16 seq
802.11 Sequence Control field
#define TCP_MAX_WINDOW_SIZE
Maxmimum advertised TCP window size.
#define STARTUP_LATE
Late startup.
A doubly-linked list entry (or list head)
static struct interface_operation tcp_xfer_operations[]
TCP data transfer interface operations.
Dynamic memory allocation.
Data transfer interfaces.
#define TCP_FIN_WAIT_1
FIN_WAIT_1.
uint32_t start
Starting offset.
#define list_empty(list)
Test whether a list is empty.
#define TCP_CLOSE_WAIT
CLOSE_WAIT.
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
struct list_head tx_queue
Transmit queue.
static void tcp_close(struct tcp_connection *tcp, int rc)
Close TCP connection.
A startup/shutdown function.
#define list_del(list)
Delete an entry from a list.
#define TCP_OPTION_WS
Code for the TCP window scale option.
#define ENOMEM
Not enough space.
static unsigned int tcp_discard(void)
Discard some cached TCP data.
#define iob_disown(iobuf)
Disown an I/O buffer.
uint32_t ts_recent
Most recent received timestamp that advanced the window.
#define TCP_OPTION_SACK_PERMITTED
Code for the TCP selective acknowledgement permitted option.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
Padded TCP selective acknowledgement permitted option (used for sending)
#define __unused
Declare a variable or data structure as unused.
#define TCP_OPTION_SACK
Code for the TCP selective acknowledgement option.
struct socket_opener tcp_socket_opener __socket_opener
TCP socket opener.
Padded TCP timestamp option (used for sending)
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
static const char * tcp_state(int state)
Name TCP state.
static struct tcp_connection * tcp_first_unclosed(void)
Find first TCP connection that has not yet been closed.
uint32_t ts_val
Received timestamp value.
A long option, as used for getopt_long()
static int tcp_rx_opts(struct tcp_connection *tcp, const struct tcp_header *tcphdr, size_t hlen, struct tcp_options *options)
Parse TCP received options.
unsigned int(* discard)(void)
Discard some cached data.
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
#define list_for_each_entry_reverse(pos, head, member)
Iterate over entries in a list in reverse order.
#define TCP_ESTABLISHED
ESTABLISHED.
static struct net_device * netdev
const char * scheme
URI protocol name.
#define TCP_CAN_SEND_DATA(state)
Can send data in current state.
Transport-network layer interface.
TCP data transfer interface has been closed.
static void tcp_rx_seq(struct tcp_connection *tcp, uint32_t seq_len)
Consume received sequence space.
static int is_pending(struct pending_operation *pending)
Check if an operation is pending.
#define TCP_TIME_WAIT
TIME_WAIT.
static void profile_start(struct profiler *profiler)
Start profiling.
static int tcp_rx_data(struct tcp_connection *tcp, uint32_t seq, struct io_buffer *iobuf)
Handle TCP received data.
uint8_t rcv_win_scale
Receive window scale.
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
#define TCP_SACK_MAX
Maximum number of selective acknowledgement blocks.
void process_add(struct process *process)
Add process to process list.
#define ENOTCONN
The socket is not connected.
uint16_t st_port
TCP/IP port.
const char * name
Protocol name.
Generalized socket address structure.
#define TCP_STATE_RCVD(flags)
TCP flags that have been received from the peer.
An object interface descriptor.
unsigned int local_port
Local port.
char * strerror(int errno)
Retrieve string representation of error number.
static size_t tcp_xmit_win(struct tcp_connection *tcp)
Calculate transmission window.
void * zalloc(size_t size)
Allocate cleared memory.
static void tcp_wait_expired(struct retry_timer *timer, int over)
Shutdown timer expired.
struct startup_fn tcp_startup_fn __startup_fn(STARTUP_LATE)
TCP shutdown function.
static int tcp_open_uri(struct interface *xfer, struct uri *uri)
Open TCP URI.
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
struct tcp_sack_block sack[TCP_SACK_MAX]
Selective acknowledgement list (in host-endian order)
static struct tcp_connection * tcp_first_unfinished(void)
Find first TCP connection that has not yet finished all operations.
#define TCP_STATE_SENT(flags)
TCP flags that have been sent in outgoing packets.
static void tcp_xfer_close(struct tcp_connection *tcp, int rc)
Close interface.
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
#define TCP_HAS_BEEN_ESTABLISHED(state)
Have ever been fully established.
static int tcp_in_window(uint32_t seq, uint32_t start, uint32_t len)
Check if TCP sequence number lies within window.
static uint32_t tcp_sack_block(struct tcp_connection *tcp, uint32_t seq, struct tcp_sack_block *sack)
Find selective acknowledgement block.
Data transfer interface opening.
static struct profiler tcp_tx_profiler __profiler
Transmit profiler.
uint32_t snd_sent
Unacknowledged sequence count.
static void process_init_stopped(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process without adding to process list.
#define TCP_CLOSING_OR_LAST_ACK
CLOSING / LAST_ACK.
static int tcp_open(struct interface *xfer, struct sockaddr *peer, struct sockaddr *local)
Open a TCP connection.
int tcp_sock_stream
Linkage hack.
const char * host
Host name.
static void tcp_rx_enqueue(struct tcp_connection *tcp, uint32_t seq, uint8_t flags, struct io_buffer *iobuf)
Enqueue received TCP packet.
#define CACHE_NORMAL
Items with a normal replacement cost.
static void tcp_expired(struct retry_timer *timer, int over)
Retransmission timer expired.
static struct xen_remove_from_physmap * remove
static struct process_descriptor tcp_process_desc
TCP process descriptor.
#define TCP_STATE_ACKED(flags)
TCP flags that have been acknowledged by the peer.
static int process_running(struct process *process)
Check if process is running.
size_t mss
Maximum segment size.
char message[32]
Message (optional)
void start_timer(struct retry_timer *timer)
Start timer.
A transport-layer protocol of the TCP/IP stack (eg.
Network device management.
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
#define TCP_OPTION_END
End of TCP options list.
uint32_t snd_win
Send window.
static int tcp_rx_syn(struct tcp_connection *tcp, uint32_t seq, struct tcp_options *options)
Handle TCP received SYN.
#define iob_reserve(iobuf, len)
#define INIT_LIST_HEAD(list)
Initialise a list head.
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
struct tcp_sack_option sackopt
void stop_timer(struct retry_timer *timer)
Stop timer.
struct process process
Transmission process.
const char * sock_ntoa(struct sockaddr *sa)
Transcribe socket address.
struct list_head list
List of which this buffer is a member.
static int tcp_progress(struct tcp_connection *tcp, struct job_progress *progress)
Report job progress.
struct list_head list
List of TCP connections.
#define TCP_FLAGS_SENDING(state)
TCP flags that are currently being sent in outgoing packets.
#define TCP_SYN_RCVD
SYN_RCVD.
struct tcp_window_scale_option wsopt
void * data
Start of data.
void step(void)
Single-step a single process.
struct uri_opener tcp_uri_opener __uri_opener
TCP URI opener.
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
static void tcp_dump_flags(struct tcp_connection *tcp, unsigned int flags)
Dump TCP flags.
struct tcpip_protocol tcp_protocol __tcpip_protocol
TCP protocol.
static void tcp_xmit_sack(struct tcp_connection *tcp, uint32_t sack_seq)
Transmit any outstanding data (with selective acknowledgement)
unsigned int uri_port(const struct uri *uri, unsigned int default_port)
Get port from URI.
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" return dest
uint32_t end
Ending offset.
uint8_t data[48]
Additional event data.
uint32_t rcv_ack
Current acknowledgement number.
static struct tcp_connection * tcp_demux(unsigned int local_port)
Identify TCP connection by local port number.
static unsigned int tcp_sack(struct tcp_connection *tcp, uint32_t seq)
Update TCP selective acknowledgement list.
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
A Uniform Resource Identifier.
static int32_t tcp_cmp(uint32_t seq1, uint32_t seq2)
Compare TCP sequence numbers.
struct mschapv2_challenge peer
Peer challenge.
struct interface xfer
Data transfer interface.
#define TCP_FINISH_TIMEOUT
TCP finish wait time.
TCP acknowledgement is pending.
static struct interface_descriptor tcp_xfer_desc
TCP data transfer interface descriptor.
#define TCP_KEEPALIVE_DELAY
TCP keepalive period.
#define TCP_PATH_MTU
Path MTU.
static void tcp_xmit(struct tcp_connection *tcp)
Transmit any outstanding data.
unsigned long currticks(void)
Get current system time in ticks.
static int tcp_xfer_deliver(struct tcp_connection *tcp, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
Deliver datagram as I/O buffer.
#define TCP_MAX_HEADER_LEN
TCP maximum header length.
#define DBG(...)
Print a debugging message.
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
TCP selective acknowledgement block.
static int tcp_rx_ack(struct tcp_connection *tcp, uint32_t ack, uint32_t win)
Handle TCP received ACK.
int tcpip_tx(struct io_buffer *iobuf, struct tcpip_protocol *tcpip_protocol, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest, struct net_device *netdev, uint16_t *trans_csum)
Transmit a TCP/IP packet.
uint16_t tcpip_chksum(const void *data, size_t len)
Calculate TCP/IP checkum.
#define ENETUNREACH
Network unreachable.
struct pending_operation pending_flags
Pending operations for SYN and FIN.
#define NULL
NULL pointer (VOID *)
#define ETIMEDOUT
Connection timed out.
#define TCP_CLOSED_GRACEFULLY(state)
Have closed gracefully.
#define TCP_CLOSED
CLOSED.
void pending_get(struct pending_operation *pending)
Mark an operation as pending.
static void tcp_process_rx_queue(struct tcp_connection *tcp)
Process receive queue.
uint16_t tcpip_continue_chksum(uint16_t partial, const void *data, size_t len)
Calculate continued TCP/IP checkum.
static LIST_HEAD(tcp_conns)
List of registered TCP connections.
int xfer_open_named_socket(struct interface *xfer, int semantics, struct sockaddr *peer, const char *name, struct sockaddr *local)
Open named socket.
static void tcp_dump_state(struct tcp_connection *tcp)
Dump TCP state transition.
#define ref_put(refcnt)
Drop reference to object.
struct tcp_sack_permitted_option spopt
uint32_t rcv_win
Receive window.
struct sockaddr_tcpip peer
Remote socket address.
#define TCP_FIN_WAIT_2
FIN_WAIT_2.
void * memset(void *dest, int character, size_t len) __nonnull