Revision a8bde059 libavformat/udp.c

View differences:

libavformat/udp.c
45 45
#define UDP_TX_BUF_SIZE 32768
46 46
#define UDP_MAX_PKT_SIZE 65536
47 47

  
48
#ifdef CONFIG_IPV6
49

  
50 48
static int udp_ipv6_set_multicast_ttl(int sockfd, int mcastTTL, struct sockaddr *addr) {
49
#ifdef IP_MULTICAST_TTL
51 50
    if (addr->sa_family == AF_INET) {
52 51
        if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &mcastTTL, sizeof(mcastTTL)) < 0) {
53 52
            perror("setsockopt(IP_MULTICAST_TTL)");
54 53
            return -1;
55 54
        }
56 55
    }
56
#endif
57
#ifdef CONFIG_IPV6
57 58
    if (addr->sa_family == AF_INET6) {
58 59
        if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &mcastTTL, sizeof(mcastTTL)) < 0) {
59 60
            perror("setsockopt(IPV6_MULTICAST_HOPS)");
60 61
            return -1;
61 62
        }
62 63
    }
64
#endif
63 65
    return 0;
64 66
}
65 67

  
66 68
static int udp_ipv6_join_multicast_group(int sockfd, struct sockaddr *addr) {
67
    struct ip_mreq   mreq;
68
    struct ipv6_mreq mreq6;
69
#ifdef IP_ADD_MEMBERSHIP
69 70
    if (addr->sa_family == AF_INET) {
71
        struct ip_mreq mreq;
72

  
70 73
        mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
71 74
        mreq.imr_interface.s_addr= INADDR_ANY;
72 75
        if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) {
......
74 77
            return -1;
75 78
        }
76 79
    }
80
#endif
81
#ifdef CONFIG_IPV6
77 82
    if (addr->sa_family == AF_INET6) {
83
        struct ipv6_mreq mreq6;
84

  
78 85
        memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr));
79 86
        mreq6.ipv6mr_interface= 0;
80 87
        if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) {
......
82 89
            return -1;
83 90
        }
84 91
    }
92
#endif
85 93
    return 0;
86 94
}
87 95

  
88 96
static int udp_ipv6_leave_multicast_group(int sockfd, struct sockaddr *addr) {
89
    struct ip_mreq   mreq;
90
    struct ipv6_mreq mreq6;
97
#ifdef IP_DROP_MEMBERSHIP
91 98
    if (addr->sa_family == AF_INET) {
99
        struct ip_mreq mreq;
100

  
92 101
        mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
93 102
        mreq.imr_interface.s_addr= INADDR_ANY;
94 103
        if (setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) {
......
96 105
            return -1;
97 106
        }
98 107
    }
108
#endif
109
#ifdef CONFIG_IPV6
99 110
    if (addr->sa_family == AF_INET6) {
111
        struct ipv6_mreq mreq6;
112

  
100 113
        memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr));
101 114
        mreq6.ipv6mr_interface= 0;
102 115
        if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) {
......
104 117
            return -1;
105 118
        }
106 119
    }
120
#endif
107 121
    return 0;
108 122
}
109 123

  
124
#ifdef CONFIG_IPV6
110 125
static struct addrinfo* udp_ipv6_resolve_host(const char *hostname, int port, int type, int family, int flags) {
111 126
    struct addrinfo hints, *res = 0;
112 127
    int error;
......
345 360
    len = sizeof(my_addr1);
346 361
    getsockname(udp_fd, (struct sockaddr *)&my_addr1, &len);
347 362
    s->local_port = ntohs(my_addr1.sin_port);
348

  
349
#ifdef IP_MULTICAST_TTL
350
    if (s->is_multicast) {
351
        if (h->flags & URL_WRONLY) {
352
            /* output */
353
            if (setsockopt(udp_fd, IPPROTO_IP, IP_MULTICAST_TTL,
354
                           &s->ttl, sizeof(s->ttl)) < 0) {
355
                perror("IP_MULTICAST_TTL");
356
                goto fail;
357
            }
358
        } else {
359
            /* input */
360
            memset(&s->mreq, 0, sizeof(s->mreq));
361
            s->mreq.imr_multiaddr = s->dest_addr.sin_addr;
362
            s->mreq.imr_interface.s_addr = htonl (INADDR_ANY);
363
            if (setsockopt(udp_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
364
                           &s->mreq, sizeof(s->mreq)) < 0) {
365
                perror("rtp: IP_ADD_MEMBERSHIP");
366
                goto fail;
367
            }
368
        }
369
    }
370
#endif
371 363
#else
372 364
    if (s->is_multicast && !(h->flags & URL_WRONLY))
373 365
        s->local_port = port;
374 366
    udp_fd = udp_ipv6_set_local(h);
375 367
    if (udp_fd < 0)
376 368
        goto fail;
369
#endif /* CONFIG_IPV6 */
377 370
    if (s->is_multicast) {
378 371
        if (h->flags & URL_WRONLY) {
372
            /* output */
379 373
            if (udp_ipv6_set_multicast_ttl(udp_fd, s->ttl, (struct sockaddr *)&s->dest_addr) < 0)
380 374
                goto fail;
381 375
        } else {
376
            /* input */
382 377
            if (udp_ipv6_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0)
383 378
                goto fail;
384 379
        }
385 380
    }
386
#endif /* CONFIG_IPV6 */
387 381

  
388 382
    if (is_output) {
389 383
        /* limit the tx buf size to limit latency */
......
458 452
{
459 453
    UDPContext *s = h->priv_data;
460 454

  
461
#ifndef CONFIG_IPV6
462
#ifdef IP_DROP_MEMBERSHIP
463
    if (s->is_multicast && !(h->flags & URL_WRONLY)) {
464
        if (setsockopt(s->udp_fd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
465
                       &s->mreq, sizeof(s->mreq)) < 0) {
466
            perror("IP_DROP_MEMBERSHIP");
467
        }
468
    }
469
#endif
470
#else
471 455
    if (s->is_multicast && !(h->flags & URL_WRONLY))
472 456
        udp_ipv6_leave_multicast_group(s->udp_fd, (struct sockaddr *)&s->dest_addr);
473
#endif
474 457
    closesocket(s->udp_fd);
475 458
    ff_network_close();
476 459
    av_free(s);

Also available in: Unified diff