Ticket #567: udp-issues-jinfei.patch

File udp-issues-jinfei.patch, 5.6 KB (added by Jakub Jermář, 10 years ago)
  • uspace/srv/net/inetsrv/pdu.c

    === modified file 'uspace/srv/net/inetsrv/pdu.c'
     
    105105    size_t offs, size_t mtu, void **rdata, size_t *rsize, size_t *roffs)
    106106{
    107107        /* Upper bound for fragment offset field */
    108         size_t fragoff_limit = 1 << (FF_FRAGOFF_h - FF_FRAGOFF_l);
     108        size_t fragoff_limit = 1 << (FF_FRAGOFF_h - FF_FRAGOFF_l+1);
    109109       
    110110        /* Verify that total size of datagram is within reasonable bounds */
    111         if (offs + packet->size > FRAG_OFFS_UNIT * fragoff_limit)
     111        if ( packet->size > FRAG_OFFS_UNIT * fragoff_limit)
    112112                return ELIMIT;
    113113       
    114114        size_t hdr_size = sizeof(ip_header_t);
  • uspace/srv/net/inetsrv/reass.c

    === modified file 'uspace/srv/net/inetsrv/reass.c'
     
    5454        link_t map_link;
    5555        /** List of fragments, @c reass_frag_t */
    5656        list_t frags;
     57        void *data;
    5758} reass_dgram_t;
    5859
    5960/** One datagram fragment */
     
    8485{
    8586        reass_dgram_t *rdg;
    8687        int rc;
    87 
    8888        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_reass_queue_packet()");
    8989
    9090        fibril_mutex_lock(&reass_dgram_map_lock);
     
    102102        rc = reass_dgram_insert_frag(rdg, packet);
    103103        if (rc != EOK)
    104104                return ENOMEM;
    105 
     105               
    106106        /* Check if datagram is complete */
    107107        if (reass_dgram_complete(rdg)) {
    108108                /* Remove it from the map */
     
    197197
    198198        frag->packet = *packet;
    199199        frag->packet.data = data_copy;
     200        memcpy(data_copy, packet->data, packet->size);
    200201
    201202        /*
    202203         * XXX Make resource-consuming attacks harder, eliminate any duplicate
     
    208209         */
    209210
    210211        link = list_first(&rdg->frags);
    211         while (link != NULL) {
     212        while (link != NULL ) {
    212213                reass_frag_t *qf = list_get_instance(link, reass_frag_t,
    213214                    dgram_link);
    214215
    215216                if (qf->packet.offs >= packet->offs)
    216217                        break;
    217 
    218                 link = link->next;
     218                if ( link->next != &rdg->frags.head)
     219                        link = link->next;
     220                else
     221                        break;
    219222        }
    220223
    221         if (link != NULL)
     224        if (link != NULL){
    222225                list_insert_after(&frag->dgram_link, link);
    223         else
     226        } else {
    224227                list_append(&frag->dgram_link, &rdg->frags);
     228        }
    225229
    226230        return EOK;
    227231}
     
    242246        /* First fragment must be at offset zero */
    243247        frag = list_get_instance(list_first(&rdg->frags), reass_frag_t,
    244248            dgram_link);
    245         if (frag->packet.offs != 0)
     249        if (frag->packet.offs != 0) {
    246250                return false;
     251        }
    247252
    248253        prev = frag;
    249254        while (true) {
    250255                link = frag->dgram_link.next;
    251                 if (link == NULL)
     256                if (link == NULL || link == (&rdg->frags.head))
    252257                        return false;
    253258
    254259                /* Each next fragment must follow immediately or overlap */
    255260                frag = list_get_instance(link, reass_frag_t, dgram_link);
    256                 if (frag->packet.offs > prev->packet.offs + prev->packet.size)
     261                if (frag->packet.offs > prev->packet.offs + prev->packet.size){
    257262                        return false;
     263                }
    258264
    259265                /* No more fragments - datagram is complete */
    260266                if (!frag->packet.mf)
     
    306312        dgram_size = frag->packet.offs + frag->packet.size;
    307313
    308314        /* Upper bound for fragment offset field */
    309         fragoff_limit = 1 << (FF_FRAGOFF_h - FF_FRAGOFF_l);
     315        fragoff_limit = 1 << (FF_FRAGOFF_h - FF_FRAGOFF_l+1);
    310316
    311317        /* Verify that total size of datagram is within reasonable bounds */
    312318        if (dgram_size > FRAG_OFFS_UNIT * fragoff_limit)
    313319                return ELIMIT;
    314320
    315         dgram.data = calloc(dgram_size, 1);
     321        dgram.data = rdg->data = calloc(dgram_size, 1);
    316322        if (dgram.data == NULL)
    317323                return ENOMEM;
    318324
     
    333339                ce = min(dgram_size, cfrag->packet.offs + cfrag->packet.size);
    334340
    335341                if (ce > cb) {
    336                         memcpy(dgram.data + cb,
     342                        memcpy(dgram.data + cb, cfrag->packet.data, cfrag->packet.size);
     343
     344/*                      memcpy(dgram.data + cb,
    337345                            cfrag->packet.data + cb - cfrag->packet.offs,
    338                             ce - cb);
     346                            ce - cb);*/
    339347                }
    340348
    341349                if (!cfrag->packet.mf)
    342350                        break;
    343351        }
    344 
    345352        return inet_recv_dgram_local(&dgram, proto);
    346353}
    347354
     
    360367                free(frag->packet.data);
    361368                free(frag);
    362369        }
    363 
     370        free(rdg->data);
    364371        free(rdg);
    365372}
    366373
  • uspace/srv/net/udp/assoc.c

    === modified file 'uspace/srv/net/udp/assoc.c'
     
    274274                return ENOMEM;
    275275
    276276        rc = udp_transmit_pdu(pdu);
     277        udp_pdu_delete(pdu);
     278
    277279        if (rc != EOK)
    278280                return EIO;
    279 
    280         udp_pdu_delete(pdu);
    281 
    282281        return EOK;
    283282}
    284283
     
    328327        int rc;
    329328
    330329        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_received(%p, %p)", rsp, msg);
     330       
     331        //timeout assoc queue; in case of client crash
    331332
    332333        assoc = udp_assoc_find_ref(rsp);
    333334        if (assoc == NULL) {
    334335                log_msg(LOG_DEFAULT, LVL_DEBUG, "No association found. Message dropped.");
    335336                /* XXX Generate ICMP error. */
    336337                /* XXX Might propagate error directly by error return. */
     338                udp_msg_delete(msg);
    337339                return;
    338340        }
    339341
  • uspace/srv/net/udp/msg.c

    === modified file 'uspace/srv/net/udp/msg.c'
     
    4949/** Delete segment. */
    5050void udp_msg_delete(udp_msg_t *msg)
    5151{
     52        free(msg->data);
    5253        free(msg);
    5354}
    5455
  • uspace/srv/net/udp/pdu.c

    === modified file 'uspace/srv/net/udp/pdu.c'
     
    196196        if (nmsg == NULL)
    197197                return ENOMEM;
    198198
    199         nmsg->data = text;
     199        //nmsg->data = text;
    200200        nmsg->data_size = length - sizeof(udp_header_t);
     201        nmsg->data = malloc(nmsg->data_size);
     202        memcpy(nmsg->data, text, nmsg->data_size);
    201203
    202204        *msg = nmsg;
    203205        return EOK;
  • uspace/srv/net/udp/udp_type.h

    === modified file 'uspace/srv/net/udp/udp_type.h'
     
    4242#include <sys/types.h>
    4343#include <inet/addr.h>
    4444
    45 #define UDP_FRAGMENT_SIZE 4096
    46 
     45#define UDP_FRAGMENT_SIZE 65535
    4746
    4847typedef enum {
    4948        UDP_EOK,