36
36
37
37
#include "core.h"
38
38
#include "port.h"
39
+ #include "name_table.h"
39
40
#include "node.h"
40
-
41
+ #include "link.h"
41
42
#include <linux/export.h>
42
43
#include "link.h"
43
44
@@ -545,6 +546,8 @@ static int dest_name_check(struct sockaddr_tipc *dest, struct msghdr *m)
545
546
{
546
547
struct tipc_cfg_msg_hdr hdr ;
547
548
549
+ if (unlikely (dest -> addrtype == TIPC_ADDR_ID ))
550
+ return 0 ;
548
551
if (likely (dest -> addr .name .name .type >= TIPC_RESERVED_TYPES ))
549
552
return 0 ;
550
553
if (likely (dest -> addr .name .name .type == TIPC_TOP_SRV ))
@@ -587,13 +590,49 @@ static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p)
587
590
return 0 ;
588
591
}
589
592
593
+ /**
594
+ * tipc_sendmcast - send multicast message
595
+ * @sock: socket structure
596
+ * @seq: destination address
597
+ * @iov: message data to send
598
+ * @dsz: total length of message data
599
+ * @timeo: timeout to wait for wakeup
600
+ *
601
+ * Called from function tipc_sendmsg(), which has done all sanity checks
602
+ * Returns the number of bytes sent on success, or errno
603
+ */
604
+ static int tipc_sendmcast (struct socket * sock , struct tipc_name_seq * seq ,
605
+ struct iovec * iov , size_t dsz , long timeo )
606
+ {
607
+ struct sock * sk = sock -> sk ;
608
+ struct tipc_sock * tsk = tipc_sk (sk );
609
+ int rc ;
610
+
611
+ do {
612
+ if (sock -> state != SS_READY ) {
613
+ rc = - EOPNOTSUPP ;
614
+ break ;
615
+ }
616
+ rc = tipc_port_mcast_xmit (& tsk -> port , seq , iov , dsz );
617
+ if (likely (rc >= 0 )) {
618
+ if (sock -> state != SS_READY )
619
+ sock -> state = SS_CONNECTING ;
620
+ break ;
621
+ }
622
+ if (rc != - ELINKCONG )
623
+ break ;
624
+ rc = tipc_wait_for_sndmsg (sock , & timeo );
625
+ } while (!rc );
626
+
627
+ return rc ;
628
+ }
590
629
591
630
/**
592
631
* tipc_sendmsg - send message in connectionless manner
593
632
* @iocb: if NULL, indicates that socket lock is already held
594
633
* @sock: socket structure
595
634
* @m: message to send
596
- * @total_len: length of message
635
+ * @dsz: amount of user data to be sent
597
636
*
598
637
* Message must have an destination specified explicitly.
599
638
* Used for SOCK_RDM and SOCK_DGRAM messages,
@@ -603,93 +642,116 @@ static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p)
603
642
* Returns the number of bytes sent on success, or errno otherwise
604
643
*/
605
644
static int tipc_sendmsg (struct kiocb * iocb , struct socket * sock ,
606
- struct msghdr * m , size_t total_len )
645
+ struct msghdr * m , size_t dsz )
607
646
{
647
+ DECLARE_SOCKADDR (struct sockaddr_tipc * , dest , m -> msg_name );
608
648
struct sock * sk = sock -> sk ;
609
649
struct tipc_sock * tsk = tipc_sk (sk );
610
650
struct tipc_port * port = & tsk -> port ;
611
- DECLARE_SOCKADDR (struct sockaddr_tipc * , dest , m -> msg_name );
612
- int needs_conn ;
651
+ struct tipc_msg * mhdr = & port -> phdr ;
652
+ struct iovec * iov = m -> msg_iov ;
653
+ u32 dnode , dport ;
654
+ struct sk_buff * buf ;
655
+ struct tipc_name_seq * seq = & dest -> addr .nameseq ;
656
+ u32 mtu ;
613
657
long timeo ;
614
- int res = - EINVAL ;
658
+ int rc = - EINVAL ;
615
659
616
660
if (unlikely (!dest ))
617
661
return - EDESTADDRREQ ;
662
+
618
663
if (unlikely ((m -> msg_namelen < sizeof (* dest )) ||
619
664
(dest -> family != AF_TIPC )))
620
665
return - EINVAL ;
621
- if (total_len > TIPC_MAX_USER_MSG_SIZE )
666
+
667
+ if (dsz > TIPC_MAX_USER_MSG_SIZE )
622
668
return - EMSGSIZE ;
623
669
624
670
if (iocb )
625
671
lock_sock (sk );
626
672
627
- needs_conn = (sock -> state != SS_READY );
628
- if (unlikely (needs_conn )) {
673
+ if (unlikely (sock -> state != SS_READY )) {
629
674
if (sock -> state == SS_LISTENING ) {
630
- res = - EPIPE ;
675
+ rc = - EPIPE ;
631
676
goto exit ;
632
677
}
633
678
if (sock -> state != SS_UNCONNECTED ) {
634
- res = - EISCONN ;
679
+ rc = - EISCONN ;
635
680
goto exit ;
636
681
}
637
682
if (tsk -> port .published ) {
638
- res = - EOPNOTSUPP ;
683
+ rc = - EOPNOTSUPP ;
639
684
goto exit ;
640
685
}
641
686
if (dest -> addrtype == TIPC_ADDR_NAME ) {
642
687
tsk -> port .conn_type = dest -> addr .name .name .type ;
643
688
tsk -> port .conn_instance = dest -> addr .name .name .instance ;
644
689
}
645
-
646
- /* Abort any pending connection attempts (very unlikely) */
647
- reject_rx_queue (sk );
648
690
}
691
+ rc = dest_name_check (dest , m );
692
+ if (rc )
693
+ goto exit ;
649
694
650
695
timeo = sock_sndtimeo (sk , m -> msg_flags & MSG_DONTWAIT );
651
- do {
652
- if (dest -> addrtype == TIPC_ADDR_NAME ) {
653
- res = dest_name_check (dest , m );
654
- if (res )
655
- break ;
656
- res = tipc_send2name (port ,
657
- & dest -> addr .name .name ,
658
- dest -> addr .name .domain ,
659
- m -> msg_iov ,
660
- total_len );
661
- } else if (dest -> addrtype == TIPC_ADDR_ID ) {
662
- res = tipc_send2port (port ,
663
- & dest -> addr .id ,
664
- m -> msg_iov ,
665
- total_len );
666
- } else if (dest -> addrtype == TIPC_ADDR_MCAST ) {
667
- if (needs_conn ) {
668
- res = - EOPNOTSUPP ;
669
- break ;
670
- }
671
- res = dest_name_check (dest , m );
672
- if (res )
673
- break ;
674
- res = tipc_port_mcast_xmit (port ,
675
- & dest -> addr .nameseq ,
676
- m -> msg_iov ,
677
- total_len );
696
+
697
+ if (dest -> addrtype == TIPC_ADDR_MCAST ) {
698
+ rc = tipc_sendmcast (sock , seq , iov , dsz , timeo );
699
+ goto exit ;
700
+ } else if (dest -> addrtype == TIPC_ADDR_NAME ) {
701
+ u32 type = dest -> addr .name .name .type ;
702
+ u32 inst = dest -> addr .name .name .instance ;
703
+ u32 domain = dest -> addr .name .domain ;
704
+
705
+ dnode = domain ;
706
+ msg_set_type (mhdr , TIPC_NAMED_MSG );
707
+ msg_set_hdr_sz (mhdr , NAMED_H_SIZE );
708
+ msg_set_nametype (mhdr , type );
709
+ msg_set_nameinst (mhdr , inst );
710
+ msg_set_lookup_scope (mhdr , tipc_addr_scope (domain ));
711
+ dport = tipc_nametbl_translate (type , inst , & dnode );
712
+ msg_set_destnode (mhdr , dnode );
713
+ msg_set_destport (mhdr , dport );
714
+ if (unlikely (!dport && !dnode )) {
715
+ rc = - EHOSTUNREACH ;
716
+ goto exit ;
678
717
}
679
- if (likely (res != - ELINKCONG )) {
680
- if (needs_conn && (res >= 0 ))
718
+ } else if (dest -> addrtype == TIPC_ADDR_ID ) {
719
+ dnode = dest -> addr .id .node ;
720
+ msg_set_type (mhdr , TIPC_DIRECT_MSG );
721
+ msg_set_lookup_scope (mhdr , 0 );
722
+ msg_set_destnode (mhdr , dnode );
723
+ msg_set_destport (mhdr , dest -> addr .id .ref );
724
+ msg_set_hdr_sz (mhdr , BASIC_H_SIZE );
725
+ }
726
+
727
+ new_mtu :
728
+ mtu = tipc_node_get_mtu (dnode , tsk -> port .ref );
729
+ rc = tipc_msg_build2 (mhdr , iov , 0 , dsz , mtu , & buf );
730
+ if (rc < 0 )
731
+ goto exit ;
732
+
733
+ do {
734
+ rc = tipc_link_xmit2 (buf , dnode , tsk -> port .ref );
735
+ if (likely (rc >= 0 )) {
736
+ if (sock -> state != SS_READY )
681
737
sock -> state = SS_CONNECTING ;
738
+ rc = dsz ;
682
739
break ;
683
740
}
684
- res = tipc_wait_for_sndmsg (sock , & timeo );
685
- if (res )
741
+ if (rc == - EMSGSIZE )
742
+ goto new_mtu ;
743
+
744
+ if (rc != - ELINKCONG )
686
745
break ;
687
- } while (1 );
746
+
747
+ rc = tipc_wait_for_sndmsg (sock , & timeo );
748
+ } while (!rc );
688
749
689
750
exit :
690
751
if (iocb )
691
752
release_sock (sk );
692
- return res ;
753
+
754
+ return rc ;
693
755
}
694
756
695
757
static int tipc_wait_for_sndpkt (struct socket * sock , long * timeo_p )
0 commit comments