Hello. Please look for a formatted version of this message on 
https://bitbucket.org/qyw/my_lwip_issues/issues/1/listening-to-a-lot-of-mutlicast-packets
  
I have met yet another strange problem. And cannot debug it.  
The code at the end of message works fine until something goes wrong in 
`recv_udp()` and program falls into `HardFault_Handler()` possible because of 
NULL-pointer.   
Let's consider stack trace:
    
    HardFault_Handler
    recv_udp
    udp_input
    ip_input
    ethernet_input
    tcpip_thread

The data flow is really big, but stack size of tcpip_thread is big too, 4096 
bytes. Please help me to debug mistakes.


        /**
         * Socket based multicast listener
         */
        void vmp_MulticastListener_task( void *args )
        {
                int sock;
                struct sockaddr_in address={0};//, mcast_addr;
                struct ip_mreq mreq;  // multicast request
                union {
                        vmp_Header_t   *h;
                        vmp_IamAlive_t *a;
                        vmp_Event_t    *e;
                        vmp_Waveform_t *w;
                } vmp;
                const uint16_t vmp_MAX_SIZE = sizeof(vmp_Waveform_t);
                
                vmp.w = malloc(vmp_MAX_SIZE);
                        
                sock = socket(AF_INET, SOCK_DGRAM, 0);
                if( sock < 0 ){
                        debugf("%s: Cannot create socket", __func__);
                        goto stopTask;
                }
                // SO_REUSEADDR mainly changes the way how wildcard addresses 
("any IP address") are treated when searching for conflicts.
                // Without SO_REUSEADDR, binding socketA to 0.0.0.0:21 and then 
binding socketB to 192.168.0.1:21 will fail 
                // (with error EADDRINUSE), since 0.0.0.0 means "any local IP 
address", thus all local IP addresses are considered 
                // in use by this socket and this includes 192.168.0.1, too. 
With SO_REUSEADDR it will succeed, since 0.0.0.0 and 
                // 192.168.0.1 are not exactly the same address, one is a 
wildcard for all local addresses and the other one is a 
                // very specific local address. Note that the statement above 
is true regardless in which order socketA and socketB 
                // are bound; without SO_REUSEADDR it will always fail, with 
SO_REUSEADDR it will always succeed.
                //\see 
http://stackoverflow.com/questions/14388706/socket-options-so-reuseaddr-and-so-reuseport-how-do-they-differ-do-they-mean-t#14388707
                {
                const int optval_true = 1;
                setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &optval_true, 
sizeof(optval_true) );
                }

                // Bind to port MULTI_SENDER_PORT at any interface.
                address.sin_family = AF_INET;
                address.sin_addr.s_addr = htonl(INADDR_ANY);  
//addr.sin_addr.s_addr = inet_addr("192.168.x.x"); 
                address.sin_port = htons(MULTI_SENDER_PORT);
                if( bind(sock, (struct sockaddr*) &address, sizeof(address)) < 
0 ){
                        debugf("%s: cannot bind socket", __func__);
                        goto stopTask;
                }
                
                // Join to the multicast group
                mreq.imr_multiaddr.s_addr = inet_addr(MULTI_SENDER_ADDRESS);  
//htonl(INADDR_ANY);  //PP_HTONL(INADDR_ANY)
                mreq.imr_interface.s_addr = htonl(INADDR_ANY);  
//inet_addr("192.168.x.x");  //PP_HTONL(INADDR_ANY)
                if( setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, 
sizeof(mreq)) < 0 ){
                        debugf("%s: cannot join multicast", __func__);
                        goto stopTask;
                }
                
                for(;;)
                {
                        struct sockaddr_in addrfrom = {0};
                        socklen_t addrfrom_len = sizeof(addrfrom);
                        int len = recvfrom(sock, vmp.w, vmp_MAX_SIZE, 0, 
(struct sockaddr*)&addrfrom, &addrfrom_len);
                        if( len>sizeof(vmp_Header_t) ){
                                debugf2("%c recved from %08x:%s:%s\n", 
vmp.h->variant, vmp.h->uid32, vmp.h->role, 
ipaddr_ntoa((ip_addr_t*)&addrfrom.sin_addr) );
                                if( vmp.h->variant == 'E' ){
                                        Role_t role = 
vmp_parseRole(vmp.h->role);
                                        if( vmp_CurrentIsSlaveOfMaster(&role) ){
                                                extern const volatile 
QueueHandle_t indication_queue;
                                                
xQueueOverwrite(indication_queue, vmp.e );
                                        }
                                }
                        }
                }
        }

-- 
Best regards
Ivan Kuvaldin

_______________________________________________
lwip-users mailing list
lwip-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/lwip-users

Reply via email to