webkit  2cdf99a9e3038c7e01b3c37e8ad903ecbe5eecf1
https://github.com/WebKit/webkit
Classes | Macros | Functions | Variables
sctp_output.c File Reference
#include <netinet/sctp_os.h>
#include <netinet/sctp_var.h>
#include <netinet/sctp_sysctl.h>
#include <netinet/sctp_header.h>
#include <netinet/sctp_pcb.h>
#include <netinet/sctputil.h>
#include <netinet/sctp_output.h>
#include <netinet/sctp_uio.h>
#include <netinet/sctp_auth.h>
#include <netinet/sctp_timer.h>
#include <netinet/sctp_asconf.h>
#include <netinet/sctp_indata.h>
#include <netinet/sctp_bsd_addr.h>
#include <netinet/sctp_input.h>
#include <netinet/sctp_crc32.h>

Classes

struct  sack_track
 

Macros

#define SCTP_MAX_GAPS_INARRAY   4
 

Functions

int sctp_is_address_in_scope (struct sctp_ifa *ifa, struct sctp_scoping *scope, int do_update)
 
struct mbufsctp_add_addresses_to_i_ia (struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_scoping *scope, struct mbuf *m_at, int cnt_inits_to, uint16_t *padding_len, uint16_t *chunk_len)
 
int sctp_is_addr_restricted (struct sctp_tcb *stcb, struct sctp_ifa *ifa)
 
int sctp_is_addr_in_ep (struct sctp_inpcb *inp, struct sctp_ifa *ifa)
 
struct sctp_ifasctp_source_address_selection (struct sctp_inpcb *inp, struct sctp_tcb *stcb, sctp_route_t *ro, struct sctp_nets *net, int non_asoc_addr_ok, uint32_t vrf_id)
 
void sctp_send_initiate (struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked SCTP_UNUSED)
 
struct mbufsctp_arethere_unrecognized_parameters (struct mbuf *in_initpkt, int param_offset, int *abort_processing, struct sctp_chunkhdr *cp, int *nat_friendly)
 
void sctp_send_initiate_ack (struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets *src_net, struct mbuf *init_pkt, int iphlen, int offset, struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh, struct sctp_init_chunk *init_chk, uint32_t vrf_id, uint16_t port, int hold_inp_lock)
 
int sctp_get_frag_point (struct sctp_tcb *stcb, struct sctp_association *asoc)
 
void sctp_toss_old_cookies (struct sctp_tcb *stcb, struct sctp_association *asoc)
 
void sctp_toss_old_asconf (struct sctp_tcb *stcb)
 
void sctp_fix_ecn_echo (struct sctp_association *asoc)
 
void sctp_move_chunks_from_net (struct sctp_tcb *stcb, struct sctp_nets *net)
 
void sctp_queue_op_err (struct sctp_tcb *stcb, struct mbuf *op_err)
 
int sctp_send_cookie_echo (struct mbuf *m, int offset, struct sctp_tcb *stcb, struct sctp_nets *net)
 
void sctp_send_heartbeat_ack (struct sctp_tcb *stcb, struct mbuf *m, int offset, int chk_length, struct sctp_nets *net)
 
void sctp_send_cookie_ack (struct sctp_tcb *stcb)
 
void sctp_send_shutdown_ack (struct sctp_tcb *stcb, struct sctp_nets *net)
 
void sctp_send_shutdown (struct sctp_tcb *stcb, struct sctp_nets *net)
 
void sctp_send_asconf (struct sctp_tcb *stcb, struct sctp_nets *net, int addr_locked)
 
void sctp_send_asconf_ack (struct sctp_tcb *stcb)
 
void sctp_chunk_output (struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_where, int so_locked SCTP_UNUSED)
 
int sctp_output (struct sctp_inpcb *inp, struct mbuf *m, struct sockaddr *addr, struct mbuf *control, struct proc *p, int flags)
 
void send_forward_tsn (struct sctp_tcb *stcb, struct sctp_association *asoc)
 
void sctp_send_sack (struct sctp_tcb *stcb, int so_locked SCTP_UNUSED)
 
void sctp_send_abort_tcb (struct sctp_tcb *stcb, struct mbuf *operr, int so_locked SCTP_UNUSED)
 
void sctp_send_shutdown_complete (struct sctp_tcb *stcb, struct sctp_nets *net, int reflect_vtag)
 
void sctp_send_shutdown_complete2 (struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh, uint32_t vrf_id, uint16_t port)
 
void sctp_send_hb (struct sctp_tcb *stcb, struct sctp_nets *net, int so_locked SCTP_UNUSED)
 
void sctp_send_ecn_echo (struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t high_tsn)
 
void sctp_send_packet_dropped (struct sctp_tcb *stcb, struct sctp_nets *net, struct mbuf *m, int len, int iphlen, int bad_crc)
 
void sctp_send_cwr (struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t high_tsn, uint8_t override)
 
void sctp_add_stream_reset_result (struct sctp_tmit_chunk *chk, uint32_t resp_seq, uint32_t result)
 
void sctp_send_deferred_reset_response (struct sctp_tcb *stcb, struct sctp_stream_reset_list *ent, int response)
 
void sctp_add_stream_reset_result_tsn (struct sctp_tmit_chunk *chk, uint32_t resp_seq, uint32_t result, uint32_t send_una, uint32_t recv_next)
 
int sctp_send_stream_reset_out_if_possible (struct sctp_tcb *stcb, int so_locked)
 
int sctp_send_str_reset_req (struct sctp_tcb *stcb, uint16_t number_entries, uint16_t *list, uint8_t send_in_req, uint8_t send_tsn_req, uint8_t add_stream, uint16_t adding_o, uint16_t adding_i, uint8_t peer_asked)
 
void sctp_send_abort (struct mbuf *m, int iphlen, struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh, uint32_t vtag, struct mbuf *cause, uint32_t vrf_id, uint16_t port)
 
void sctp_send_operr_to (struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh, uint32_t vtag, struct mbuf *cause, uint32_t vrf_id, uint16_t port)
 
int sctp_sosend (struct socket *so, struct sockaddr *addr, struct uio *uio, struct mbuf *top, struct mbuf *control, int flags, struct proc *p)
 
int sctp_lower_sosend (struct socket *so, struct sockaddr *addr, struct uio *uio, struct mbuf *i_pak, struct mbuf *control, int flags, struct sctp_sndrcvinfo *srcv, struct proc *p)
 
struct mbufsctp_add_auth_chunk (struct mbuf *m, struct mbuf **m_end, struct sctp_auth_chunk **auth_ret, uint32_t *offset, struct sctp_tcb *stcb, uint8_t chunk)
 

Variables

const struct sack_track sack_array [256]
 

Macro Definition Documentation

◆ SCTP_MAX_GAPS_INARRAY

#define SCTP_MAX_GAPS_INARRAY   4

Function Documentation

◆ sctp_add_addresses_to_i_ia()

struct mbuf* sctp_add_addresses_to_i_ia ( struct sctp_inpcb inp,
struct sctp_tcb stcb,
struct sctp_scoping scope,
struct mbuf m_at,
int  cnt_inits_to,
uint16_t padding_len,
uint16_t chunk_len 
)

◆ sctp_add_auth_chunk()

struct mbuf* sctp_add_auth_chunk ( struct mbuf m,
struct mbuf **  m_end,
struct sctp_auth_chunk **  auth_ret,
uint32_t offset,
struct sctp_tcb stcb,
uint8_t  chunk 
)

◆ sctp_add_stream_reset_result()

void sctp_add_stream_reset_result ( struct sctp_tmit_chunk chk,
uint32_t  resp_seq,
uint32_t  result 
)

◆ sctp_add_stream_reset_result_tsn()

void sctp_add_stream_reset_result_tsn ( struct sctp_tmit_chunk chk,
uint32_t  resp_seq,
uint32_t  result,
uint32_t  send_una,
uint32_t  recv_next 
)

◆ sctp_arethere_unrecognized_parameters()

struct mbuf* sctp_arethere_unrecognized_parameters ( struct mbuf in_initpkt,
int  param_offset,
int *  abort_processing,
struct sctp_chunkhdr cp,
int *  nat_friendly 
)

◆ sctp_chunk_output()

void sctp_chunk_output ( struct sctp_inpcb inp,
struct sctp_tcb stcb,
int  from_where,
int so_locked  SCTP_UNUSED 
)

◆ sctp_fix_ecn_echo()

void sctp_fix_ecn_echo ( struct sctp_association asoc)

◆ sctp_get_frag_point()

int sctp_get_frag_point ( struct sctp_tcb stcb,
struct sctp_association asoc 
)

◆ sctp_is_addr_in_ep()

int sctp_is_addr_in_ep ( struct sctp_inpcb inp,
struct sctp_ifa ifa 
)

◆ sctp_is_addr_restricted()

int sctp_is_addr_restricted ( struct sctp_tcb stcb,
struct sctp_ifa ifa 
)

◆ sctp_is_address_in_scope()

int sctp_is_address_in_scope ( struct sctp_ifa ifa,
struct sctp_scoping scope,
int  do_update 
)

◆ sctp_lower_sosend()

int sctp_lower_sosend ( struct socket so,
struct sockaddr *  addr,
struct uio uio,
struct mbuf i_pak,
struct mbuf control,
int  flags,
struct sctp_sndrcvinfo srcv,
struct proc p 
)

Pre-screen address, if one is given the sin-len must be set correctly!

◆ sctp_move_chunks_from_net()

void sctp_move_chunks_from_net ( struct sctp_tcb stcb,
struct sctp_nets net 
)

◆ sctp_output()

int sctp_output ( struct sctp_inpcb inp,
struct mbuf m,
struct sockaddr *  addr,
struct mbuf control,
struct proc p,
int  flags 
)

◆ sctp_queue_op_err()

void sctp_queue_op_err ( struct sctp_tcb stcb,
struct mbuf op_err 
)

◆ sctp_send_abort()

void sctp_send_abort ( struct mbuf m,
int  iphlen,
struct sockaddr *  src,
struct sockaddr *  dst,
struct sctphdr sh,
uint32_t  vtag,
struct mbuf cause,
uint32_t  vrf_id,
uint16_t  port 
)

◆ sctp_send_abort_tcb()

void sctp_send_abort_tcb ( struct sctp_tcb stcb,
struct mbuf operr,
int so_locked  SCTP_UNUSED 
)

◆ sctp_send_asconf()

void sctp_send_asconf ( struct sctp_tcb stcb,
struct sctp_nets net,
int  addr_locked 
)

◆ sctp_send_asconf_ack()

void sctp_send_asconf_ack ( struct sctp_tcb stcb)

◆ sctp_send_cookie_ack()

void sctp_send_cookie_ack ( struct sctp_tcb stcb)

◆ sctp_send_cookie_echo()

int sctp_send_cookie_echo ( struct mbuf m,
int  offset,
struct sctp_tcb stcb,
struct sctp_nets net 
)

◆ sctp_send_cwr()

void sctp_send_cwr ( struct sctp_tcb stcb,
struct sctp_nets net,
uint32_t  high_tsn,
uint8_t  override 
)

◆ sctp_send_deferred_reset_response()

void sctp_send_deferred_reset_response ( struct sctp_tcb stcb,
struct sctp_stream_reset_list ent,
int  response 
)

◆ sctp_send_ecn_echo()

void sctp_send_ecn_echo ( struct sctp_tcb stcb,
struct sctp_nets net,
uint32_t  high_tsn 
)

◆ sctp_send_hb()

void sctp_send_hb ( struct sctp_tcb stcb,
struct sctp_nets net,
int so_locked  SCTP_UNUSED 
)

◆ sctp_send_heartbeat_ack()

void sctp_send_heartbeat_ack ( struct sctp_tcb stcb,
struct mbuf m,
int  offset,
int  chk_length,
struct sctp_nets net 
)

◆ sctp_send_initiate()

void sctp_send_initiate ( struct sctp_inpcb inp,
struct sctp_tcb stcb,
int so_locked  SCTP_UNUSED 
)

◆ sctp_send_initiate_ack()

void sctp_send_initiate_ack ( struct sctp_inpcb inp,
struct sctp_tcb stcb,
struct sctp_nets src_net,
struct mbuf init_pkt,
int  iphlen,
int  offset,
struct sockaddr *  src,
struct sockaddr *  dst,
struct sctphdr sh,
struct sctp_init_chunk init_chk,
uint32_t  vrf_id,
uint16_t  port,
int  hold_inp_lock 
)

◆ sctp_send_operr_to()

void sctp_send_operr_to ( struct sockaddr *  src,
struct sockaddr *  dst,
struct sctphdr sh,
uint32_t  vtag,
struct mbuf cause,
uint32_t  vrf_id,
uint16_t  port 
)

◆ sctp_send_packet_dropped()

void sctp_send_packet_dropped ( struct sctp_tcb stcb,
struct sctp_nets net,
struct mbuf m,
int  len,
int  iphlen,
int  bad_crc 
)

We don't respond with an PKT-DROP to an ABORT or PKT-DROP. We also do not respond to an INIT-ACK, because we can't know if the initiation tag is correct or not.

◆ sctp_send_sack()

void sctp_send_sack ( struct sctp_tcb stcb,
int so_locked  SCTP_UNUSED 
)

◆ sctp_send_shutdown()

void sctp_send_shutdown ( struct sctp_tcb stcb,
struct sctp_nets net 
)

◆ sctp_send_shutdown_ack()

void sctp_send_shutdown_ack ( struct sctp_tcb stcb,
struct sctp_nets net 
)

◆ sctp_send_shutdown_complete()

void sctp_send_shutdown_complete ( struct sctp_tcb stcb,
struct sctp_nets net,
int  reflect_vtag 
)

◆ sctp_send_shutdown_complete2()

void sctp_send_shutdown_complete2 ( struct sockaddr *  src,
struct sockaddr *  dst,
struct sctphdr sh,
uint32_t  vrf_id,
uint16_t  port 
)

◆ sctp_send_str_reset_req()

int sctp_send_str_reset_req ( struct sctp_tcb stcb,
uint16_t  number_entries,
uint16_t list,
uint8_t  send_in_req,
uint8_t  send_tsn_req,
uint8_t  add_stream,
uint16_t  adding_o,
uint16_t  adding_i,
uint8_t  peer_asked 
)

◆ sctp_send_stream_reset_out_if_possible()

int sctp_send_stream_reset_out_if_possible ( struct sctp_tcb stcb,
int  so_locked 
)

◆ sctp_sosend()

int sctp_sosend ( struct socket so,
struct sockaddr *  addr,
struct uio uio,
struct mbuf top,
struct mbuf control,
int  flags,
struct proc p 
)

◆ sctp_source_address_selection()

struct sctp_ifa* sctp_source_address_selection ( struct sctp_inpcb inp,
struct sctp_tcb stcb,
sctp_route_t ro,
struct sctp_nets net,
int  non_asoc_addr_ok,
uint32_t  vrf_id 
)

Rules:

  • Find the route if needed, cache if I can.
  • Look at interface address in route, Is it in the bound list. If so we have the best source.
  • If not we must rotate amongst the addresses.

Cavets and issues

Do we need to pay attention to scope. We can have a private address or a global address we are sourcing or sending to. So if we draw it out zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

For V4

source * dest * result

Private * Global * NAT

Private * Private * No problem

Global * Private * Huh, How will this work?

Global * Global * No Problem

zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

For V6

source * dest * result

Linklocal * Global *

Linklocal * Linklocal * No problem

Global * Linklocal * Huh, How will this work?

Global * Global * No Problem

zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

And then we add to that what happens if there are multiple addresses assigned to an interface. Remember the ifa on a ifn is a linked list of addresses. So one interface can have more than one IP address. What happens if we have both a private and a global address? Do we then use context of destination to sort out which one is best? And what about NAT's sending P->G may get you a NAT translation, or should you select the G thats on the interface in preference.

Decisions:

  • count the number of addresses on the interface.
  • if it is one, no problem except case . For we will assume a NAT out there.
  • if there are more than one, then we need to worry about scope P or G. We should prefer G -> G and P -> P if possible. Then as a secondary fall back to mixed types G->P being a last ditch one.
  • The above all works for bound all, but bound specific we need to use the same concept but instead only consider the bound addresses. If the bound set is NOT assigned to the interface then we must use rotation amongst the bound addresses..

◆ sctp_toss_old_asconf()

void sctp_toss_old_asconf ( struct sctp_tcb stcb)

◆ sctp_toss_old_cookies()

void sctp_toss_old_cookies ( struct sctp_tcb stcb,
struct sctp_association asoc 
)

◆ send_forward_tsn()

void send_forward_tsn ( struct sctp_tcb stcb,
struct sctp_association asoc 
)

Variable Documentation

◆ sack_array

const struct sack_track sack_array[256]