void rel_demux (const struct config_common *cc, const struct sockaddr_storage *ss, packet_t *pkt, size_t len) { assert(cc); assert(ss); assert(pkt); assert(len >= 0); rel_t *r; for (r = rel_list; r != NULL; r = r->next) { if (addreq(ss, &r->ss)) { rel_recvpkt(r, pkt, len); return; } } /* Before we create a new rel_t, we need to check * that this packet has a seqno == 1, otherwise * we're starting a flow part way in, and that's * against the rules. */ if (ntohl(pkt->seqno) != 1) { return; } /* If we reach here, then we need a new rel_t * for this connection, so we add it at the * head of the linked list of rel_t objects. */ rel_t *new_r = rel_create (NULL, ss, cc); rel_recvpkt(new_r, pkt, len); }
/* This function only gets called when the process is running as a * server and must handle connections from multiple clients. You have * to look up the rel_t structure based on the address in the * sockaddr_storage passed in. If this is a new connection (sequence * number 1), you will need to allocate a new conn_t using rel_create * (). (Pass rel_create NULL for the conn_t, so it will know to * allocate a new connection.) */ void rel_demux (const struct config_common *cc, const struct sockaddr_storage *ss, packet_t *pkt, size_t len) { if (!check_valid(pkt, len)) return; rel_t * r = rel_list; while (r) { if (r->ss && addreq(ss, r->ss)) { break; } r = r->next; } if (!r) { if (ntohl(pkt->seqno) == 1) { r = rel_create(NULL, ss, cc); } else { return; } } rel_recvpkt(r, pkt, len); }