diff --git a/octoserve/igmp.c b/octoserve/igmp.c index 98d1661..3963df9 100644 --- a/octoserve/igmp.c +++ b/octoserve/igmp.c @@ -51,7 +51,11 @@ void proc_igmp(struct octoserve *os, uint8_t *b, int l, uint8_t *macheader) if (hl + 1 > l) return; - //dump(b, l); +//22:45:32.073241 IP edge > 239.7.1.1: igmp v2 report 239.7.1.1 +//0x0000: 0100 5e07 0101 089e 01b2 03c9 0800 46c0 +//0x0010: 0020 0000 4000 0102 3159 c0a8 020e ef07 +//0x0020: 0101 9404 0000 1600 f9f6 ef07 0101 + dump(b, l); sprintf(sd, "%03d.%03d.%03d.%03d -> %03d.%03d.%03d.%03d", b[12], b[13], b[14], b[15], b[16], b[17], b[18], b[19]); @@ -82,7 +86,8 @@ void proc_igmp(struct octoserve *os, uint8_t *b, int l, uint8_t *macheader) s = (uint8_t *) &(((struct sockaddr_in *) &os->ssdp.sadr)->sin_addr); a1 = (b[12] << 24) | (b[13] << 16) | (b[14] << 8) | b[15]; a2 = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3]; - dbgprintf(DEBUG_IGMP, "%08x < %08x ? %s\n", a1, a2, (a1 < a2) ? "yes" : "no"); + dbgprintf(DEBUG_IGMP, "%08x < %08x ? %s\n", a1, a2, + (a1 < a2) ? "yes" : "no"); if (a1 < a2) { /* somebody else with lower IP is already sending queries */ os->igmp_mode = 3; @@ -92,8 +97,7 @@ void proc_igmp(struct octoserve *os, uint8_t *b, int l, uint8_t *macheader) dbgprintf(DEBUG_IGMP, "IGMP slave, tag = %u, timeout = %u\n", os->igmp_tag, os->igmp_timeout); } else - dbgprintf(DEBUG_IGMP, "IGMP master, tag = %u, timeout = %u\n", - os->igmp_tag, os->igmp_timeout); + dbgprintf(DEBUG_IGMP, "IGMP master, tag = %u\n", os->igmp_tag); break; } case 0x12: @@ -177,6 +181,18 @@ static void calc_cs(uint8_t *m, uint32_t len) m[3] = cs & 0xff; } +/*22:42:32.973024 IP octonet > all-systems.mcast.net: igmp query v3 +0x0000: 0100 5e00 0001 5484 7b00 141a 0800 4600 +0x0010: 0024 6682 4000 0102 db58 c0a8 024f e000 +0x0020: 0001 9404 0000 1164 ec1e 0000 0000 027d +0x0030: 0000 0000 0000 0000 0000 0000 +22:41:49.696510 IP fuckoff > all-systems.mcast.net: igmp query v2 +0x0000: 0100 5e00 0001 30b5 c2aa 24b6 0800 46c0 +0x0010: 0020 0000 4000 0102 40a6 c0a8 02c8 e000 +0x0020: 0001 9404 0000 1164 ee9b 0000 0000 0000 +0x0030: 0000 0000 0000 0000 0000 0000 +*/ + void send_igmp_query(struct octoserve *os, uint8_t *group, uint8_t timeout) { uint8_t msg[] = { 0x11, 0x64, 0x00, 0x00, @@ -218,7 +234,7 @@ void check_igmp(struct octoserve *os) switch (os->igmp_mode) { case 0: if (tdiff > 124) { - os->igmp_timeout = 11; + os->igmp_timeout = 10; dbgprintf(DEBUG_IGMP, "%u: IGMP master query, tag = %u, timeout = %u\n", t, os->igmp_tag, os->igmp_timeout); @@ -226,15 +242,18 @@ void check_igmp(struct octoserve *os) send_igmp_query(os, 0, 0); os->igmp_time = t; os->igmp_mode = 1; +#if 0 if (os->igmp_robust) { os->igmp_robust--; os->igmp_time -= 94; } +#endif } break; case 1: if (tdiff > os->igmp_timeout) { - dbgprintf(DEBUG_IGMP, "%u: IGMP timeout, tag = %u\n", t, os->igmp_tag); + dbgprintf(DEBUG_IGMP, "%u: IGMP timeout, tag = %u, tdiff = %u\n", + t, os->igmp_tag, tdiff); os->igmp_mode = 0; } break; diff --git a/octoserve/octoserve.c b/octoserve/octoserve.c index 895e419..177bfd6 100644 --- a/octoserve/octoserve.c +++ b/octoserve/octoserve.c @@ -480,7 +480,7 @@ static void check_mccs(struct ossess *sess) if (tdiff >= 2) { sess->mcc_state = 0; sess->mcc_time = t; - printf("%u: mcc_state 2 done, tag = %d\n", t, sess->mcc_tag); + printf("%u: mcc_state 3 done, tag = %d\n", t, sess->mcc_tag); update = 1; } break; @@ -498,6 +498,13 @@ void session_timeout(struct ossess *sess) dbgprintf(DEBUG_RTSP, "new timeout %d\n", sess->timeout); } +void session_mc_timeout(struct ossess *sess) +{ + mtime(&sess->mc_timeout); + sess->timeout += 260; + dbgprintf(DEBUG_IGMP, "new mc timeout %d\n", sess->timeout); +} + void check_session_timeouts(struct octoserve *os) { time_t t; @@ -567,6 +574,7 @@ static struct ossess *alloc_session(struct octoserve *os) oss->nsfd = -1; oss->timeout_len = 60; session_timeout(oss); + session_mc_timeout(oss); LIST_INIT(&oss->mccs); mtime(&oss->mcc_time); dbgprintf(DEBUG_SYS, @@ -1582,7 +1590,7 @@ void mc_check(struct ossess *sess, int update) for (mcc = sess->mccs.lh_first; mcc; mcc = next) { next = mcc->mcc.le_next; if (((sess->mcc_state == 0) && (sess->mcc_tag != mcc->tag)) || - (((os->igmp_mode & 1) == 0) && (os->igmp_tag != mcc->gtag))) { + (((os->igmp_mode & 1) == 0) && (os->igmp_tag - mcc->gtag) > 1)) { printf("removed client at %u.%u.%u.%u\n", mcc->ip[0], mcc->ip[1], mcc->ip[2], mcc->ip[3]); printf("mcc_tags: %d %d\n", sess->mcc_tag, mcc->tag); @@ -1638,6 +1646,7 @@ void mc_join(struct octoserve *os, uint8_t *ip, uint8_t *mac, uint8_t *group) if ((sess = match_session(os, group)) == NULL) goto out; + session_mc_timeout(sess); printf("matched session %d to join %u.%u.%u.%u\n", sess->nr, ip[0], ip[1], ip[2], ip[3]); for (mcc = sess->mccs.lh_first; mcc; mcc = mcc->mcc.le_next) @@ -2394,7 +2403,8 @@ static int alloc_igmp_raw_socket(struct octoserve *os) { 0x15, 0, 3, 0x00000800 }, { 0x30, 0, 0, 0x00000017 }, { 0x15, 0, 1, 0x00000002 }, - { 0x6, 0, 0, 0x0000ffff }, + //{ 0x6, 0, 0, 0x0000ffff }, + { 0x6, 0, 0, 0x00040000 }, { 0x6, 0, 0, 0x00000000 }, }; struct sock_fprog sfprog; @@ -2505,11 +2515,13 @@ static void os_serve(struct octoserve *os) num = select(mfd + 1, &fds, NULL, NULL, &timeout); if (num < 0) break; +#if 0 if (FD_ISSET(os->igmp_sock, &fds)) { n = recvfrom(os->igmp_sock, buf, sizeof(buf), 0, &cadr, &clen); if (n > 0) proc_igmp(os, buf, n, NULL); } +#endif if (FD_ISSET(os->igmp_rsock, &fds)) { n = recvfrom(os->igmp_rsock, buf, sizeof(buf), 0, &cadr, &clen); if (n > 14) diff --git a/octoserve/octoserve.h b/octoserve/octoserve.h index e9ca5b0..eb774f9 100644 --- a/octoserve/octoserve.h +++ b/octoserve/octoserve.h @@ -309,6 +309,8 @@ struct ossess { int playing; int nr; + /* timers */ + time_t mc_timeout; uint32_t timeout_len; time_t timeout; @@ -324,6 +326,7 @@ struct ossess { uint32_t mcc_port_vec_set; uint32_t port_vec; uint32_t port_vec_set; + }; enum { @@ -487,8 +490,8 @@ struct octoserve { uint32_t igmp_mode; uint32_t igmp_tag; uint32_t igmp_timeout; - uint32_t igmp_robust; - + uint32_t igmp_robust; + int mld_sock; int has_switch; int strict;