@@ -42,6 +42,10 @@ typedef struct internal_socket_s {
4242 ns_list_link_t link ;
4343} internal_socket_t ;
4444
45+ const uint8_t COAP_MULTICAST_ADDR_LINK_LOCAL [16 ] = { 0xff , 0x02 , [15 ] = 0xfd }; // ff02::fd, COAP link-local multicast (rfc7390)
46+ const uint8_t COAP_MULTICAST_ADDR_ADMIN_LOCAL [16 ] = { 0xff , 0x03 , [15 ] = 0xfd }; // ff02::fd, COAP admin-local multicast (rfc7390)
47+ const uint8_t COAP_MULTICAST_ADDR_SITE_LOCAL [16 ] = { 0xff , 0x05 , [15 ] = 0xfd }; // ff05::fd, COAP site-local multicast (rfc7390)
48+
4549static NS_LIST_DEFINE (socket_list , internal_socket_t , link ) ;
4650
4751static void timer_cb (void * param );
@@ -223,7 +227,9 @@ static secure_session_t *secure_session_find(internal_socket_t *parent, const ui
223227
224228static internal_socket_t * int_socket_create (uint16_t listen_port , bool use_ephemeral_port , bool is_secure , bool real_socket , bool bypassSec , int8_t socket_interface_selection )
225229{
230+ ns_ipv6_mreq_t ns_ipv6_mreq ;
226231 internal_socket_t * this = ns_dyn_mem_alloc (sizeof (internal_socket_t ));
232+
227233 if (!this ) {
228234 return NULL ;
229235 }
@@ -265,10 +271,22 @@ static internal_socket_t *int_socket_create(uint16_t listen_port, bool use_ephem
265271
266272 // Set socket option to receive packet info
267273 socket_setsockopt (this -> socket , SOCKET_IPPROTO_IPV6 , SOCKET_IPV6_RECVPKTINFO , & (const bool ) {1 }, sizeof (bool ));
268- if (socket_interface_selection != -1 ) {
269- // Select socket interface if selection requested
270- socket_setsockopt (this -> socket , SOCKET_IPPROTO_IPV6 , SOCKET_INTERFACE_SELECT , & socket_interface_selection , sizeof (int8_t ));
274+ if (socket_interface_selection > 0 ) {
275+ // Interface selection requested as socket_interface_selection set
276+ socket_setsockopt (this -> socket , SOCKET_IPPROTO_IPV6 , SOCKET_INTERFACE_SELECT , & socket_interface_selection , sizeof (socket_interface_selection ));
271277 }
278+
279+ // Join COAP multicast group(s)
280+ ns_ipv6_mreq .ipv6mr_interface = socket_interface_selection ; // It is OK to use 0 or real interface id here
281+
282+ memcpy (ns_ipv6_mreq .ipv6mr_multiaddr , COAP_MULTICAST_ADDR_LINK_LOCAL , 16 );
283+ socket_setsockopt (this -> socket , SOCKET_IPPROTO_IPV6 , SOCKET_IPV6_JOIN_GROUP , & ns_ipv6_mreq , sizeof (ns_ipv6_mreq ));
284+
285+ memcpy (ns_ipv6_mreq .ipv6mr_multiaddr , COAP_MULTICAST_ADDR_ADMIN_LOCAL , 16 );
286+ socket_setsockopt (this -> socket , SOCKET_IPPROTO_IPV6 , SOCKET_IPV6_JOIN_GROUP , & ns_ipv6_mreq , sizeof (ns_ipv6_mreq ));
287+
288+ memcpy (ns_ipv6_mreq .ipv6mr_multiaddr , COAP_MULTICAST_ADDR_SITE_LOCAL , 16 );
289+ socket_setsockopt (this -> socket , SOCKET_IPPROTO_IPV6 , SOCKET_IPV6_JOIN_GROUP , & ns_ipv6_mreq , sizeof (ns_ipv6_mreq ));
272290 } else {
273291 this -> socket = virtual_socket_id_allocate ();
274292 }
0 commit comments