func: static int sctp_connect(struct sock *sk, struct sockaddr int addr_len) struct sctp_af * af ; af = sctp_get_af_specific ( addr -> sa_family ); if ( ! af || addr_len < af -> sockaddr_len )  err = __sctp_connect ( sk , addr , af -> sockaddr_len , NULL ); static int __sctp_connect(struct sock struct sockaddr int sctp_assoc_t *assoc_id) struct net * net = sock_net ( sk ) ; struct sctp_sock * sp ; struct sctp_endpoint * ep ; struct sctp_association * asoc = NULL ; struct sctp_association * asoc2 ; struct sctp_transport * transport ; union sctp_addr to ; sctp_scope_t scope ; int walk_size = 0 ; void * addr_buf ; unsigned short port ; sp = sctp_sk ( sk ); ep = sp -> ep; if ( sctp_sstate ( sk , ESTABLISHED ) || sctp_sstate ( sk , CLOSING ) || ( sctp_style ( sk , TCP ) && sctp_sstate ( sk , LISTENING ) ) )  addr_buf = kaddrs; while ( walk_size < addrs_size )  struct sctp_af * af ; if ( walk_size + sizeof ( sa_family_t ) > addrs_size )  sa_addr = addr_buf; af = sctp_get_af_specific ( sa_addr -> sa . sa_family ); if ( ! af || ( walk_size + af -> sockaddr_len ) > addrs_size )  port = ntohs ( sa_addr -> v4 . sin_port ); memcpy ( & to , sa_addr , af -> sockaddr_len ); err = sctp_verify_addr ( sk , & to , af -> sockaddr_len ); static inline int sctp_verify_addr(struct sock *sk, union sctp_addr int len) af = sctp_sockaddr_af ( sctp_sk ( sk ) , addr , len ); static struct sctp_af *sctp_sockaddr_af(struct sctp_sock union sctp_addr *addr, int len) if ( len < sizeof ( struct sockaddr ) )  if ( addr -> sa . sa_family == AF_INET6 && ipv6_addr_v4mapped ( & addr -> v6 . sin6_addr ) )  if ( ! opt -> pf -> af_supported ( AF_INET , opt ) )  if ( ! opt -> pf -> af_supported ( addr -> sa . sa_family , opt ) )  af = sctp_get_af_specific ( addr -> sa . sa_family ); if ( len < af -> sockaddr_len )  return af ; if ( ! af )  if ( ! af -> addr_valid ( addr , sctp_sk ( sk ) , NULL ) )  if ( ! sctp_sk ( sk ) -> pf -> send_verify ( sctp_sk ( sk ) , ( addr ) ) )  if ( err )  if ( asoc && asoc -> peer . port && asoc -> peer . port != port )  asoc2 = sctp_endpoint_lookup_assoc ( ep , & to , & transport ); if ( asoc2 && asoc2 != asoc )  if ( asoc2 -> state >= SCTP_STATE_ESTABLISHED )  if ( sctp_endpoint_is_peeled_off ( ep , & to ) )  if ( ! asoc )  if ( ! ep -> base . bind_addr . port )  if ( sctp_autobind ( sk ) )  static int sctp_autobind(struct sock *sk) af = sctp_sk ( sk ) -> pf -> af; port = htons ( inet_sk ( sk ) -> inet_num ); af -> inaddr_any ( & autoaddr , port ); return sctp_do_bind ( sk , & autoaddr , af -> sockaddr_len ) ; static int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len) struct net * net = sock_net ( sk ) ; struct sctp_sock * sp = sctp_sk ( sk ) ; struct sctp_endpoint * ep = sp -> ep ; struct sctp_bind_addr * bp = & ep -> base . bind_addr ; af = sctp_sockaddr_af ( sp , addr , len ); static struct sctp_af *sctp_sockaddr_af(struct sctp_sock union sctp_addr *addr, int len) if ( len < sizeof ( struct sockaddr ) )  if ( addr -> sa . sa_family == AF_INET6 && ipv6_addr_v4mapped ( & addr -> v6 . sin6_addr ) )  if ( ! opt -> pf -> af_supported ( AF_INET , opt ) )  if ( ! opt -> pf -> af_supported ( addr -> sa . sa_family , opt ) )  af = sctp_get_af_specific ( addr -> sa . sa_family ); if ( len < af -> sockaddr_len )  return af ; if ( ! af )  pr_debug ( "%s: sk:%p, newaddr:%p, len:%d EINVAL\n" , __func__ , sk , addr , len ); snum = ntohs ( addr -> v4 . sin_port ); pr_debug ( "%s: sk:%p, new addr:%pISc, port:%d, new port:%d, len:%d\n" , __func__ , sk , & addr -> sa , bp -> port , snum , len ); if ( ! sp -> pf -> bind_verify ( sp , addr ) )  if ( bp -> port )  if ( ! snum )  snum = bp -> port; if ( snum != bp -> port )  pr_debug ( "%s: new port %d doesn't match existing port "%d\n" , __func__ , snum , bp -> port ) if ( snum && snum < PROT_SOCK && ! ns_capable ( net -> user_ns , CAP_NET_BIND_SERVICE ) )  if ( sctp_bind_addr_match ( bp , addr , sp ) )  addr -> v4 . sin_port = htons ( snum ); if ( ret = sctp_get_port_local ( sk , addr ) )  static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr) snum = ntohs ( addr -> v4 . sin_port ); pr_debug ( "%s: begins, snum:%d\n" , __func__ , snum ); if ( snum == 0 )  struct net * net = sock_net ( sk ) ; inet_get_local_port_range ( net , & low , & high ); if ( inet_is_local_reserved_port ( net , rover ) )  index = sctp_phashfn ( sock_net ( sk ) , rover ); head = & sctp_port_hashtable [ index ]; spin_lock ( & head -> lock ); sctp_for_each_hentry ( pp , & head -> chain ) if ( ( pp -> port == rover ) && net_eq ( sock_net ( sk ) , pp -> net ) )  spin_unlock ( & head -> lock ); head = & sctp_port_hashtable [ sctp_phashfn ( sock_net ( sk ) , snum ) ]; spin_lock ( & head -> lock ); sctp_for_each_hentry ( pp , & head -> chain ) if ( ( pp -> port == snum ) && net_eq ( pp -> net , sock_net ( sk ) ) )  int reuse = sk -> sk_reuse ; if ( pp -> fastreuse && sk -> sk_reuse && sk -> sk_state != SCTP_SS_LISTENING )  if ( sk == sk2 || ( reuse && sk2 -> sk_reuse && sk2 -> sk_state != SCTP_SS_LISTENING ) )  if ( sctp_bind_addr_conflict ( & ep2 -> base . bind_addr , addr , sctp_sk ( sk2 ) , sctp_sk ( sk ) ) )  if ( ! pp && ! ( pp = sctp_bucket_create ( head , sock_net ( sk ) , snum ) ) )  static struct sctp_bind_bucket struct sctp_bind_hashbucket *head, struct net *net, unsigned short snum) pp -> port = snum; pp -> fastreuse = 0; INIT_HLIST_HEAD ( & pp -> owner ); pp -> net = net; hlist_add_head ( & pp -> node , & head -> chain ); return pp ; if ( hlist_empty ( & pp -> owner ) )  if ( sk -> sk_reuse && sk -> sk_state != SCTP_SS_LISTENING )  pp -> fastreuse = 1; pp -> fastreuse = 0; if ( pp -> fastreuse && ( ! sk -> sk_reuse || sk -> sk_state == SCTP_SS_LISTENING ) )  pp -> fastreuse = 0; if ( ! sctp_sk ( sk ) -> bind_hash )  inet_sk ( sk ) -> inet_num = snum; sk_add_bind_node ( sk , & pp -> owner ); sctp_sk ( sk ) -> bind_hash = pp; spin_unlock ( & head -> lock ); if ( ! bp -> port )  bp -> port = inet_sk ( sk ) -> inet_num; ret = sctp_add_bind_addr ( bp , addr , af -> sockaddr_len , SCTP_ADDR_SRC , GFP_ATOMIC ); if ( ! ret )  inet_sk ( sk ) -> inet_sport = htons ( inet_sk ( sk ) -> inet_num ); sp -> pf -> to_sk_saddr ( addr , sk ); return ret ; if ( ep -> base . bind_addr . port < PROT_SOCK && ! ns_capable ( net -> user_ns , CAP_NET_BIND_SERVICE ) )  scope = sctp_scope ( & to ); asoc = sctp_association_new ( ep , sk , scope , GFP_KERNEL ); if ( ! asoc )  err = sctp_assoc_set_bind_addr_from_ep ( asoc , scope , GFP_KERNEL ); if ( err < 0 )  transport = sctp_assoc_add_peer ( asoc , & to , GFP_KERNEL , SCTP_UNKNOWN ); if ( ! transport )  addr_buf += af -> sockaddr_len; walk_size += af -> sockaddr_len; pr_debug ( "%s: took out_free path with asoc:%p kaddrs:%p err:%d\n" , __func__ , asoc , kaddrs , err ); return err ; 