From patchwork Thu Apr 11 07:45:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SWduamF0b3ZpxIcsIExhemFyIChSUyk=?= X-Patchwork-Id: 48007 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:c90a:b0:1a7:a0dc:8de5 with SMTP id gx10csp134225pzb; Thu, 11 Apr 2024 00:45:48 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCXc81If+cBYP9yPnIikN/BcWCWJkziKr72fUVh6M2lw1LDOj9Y3lKCkpfgEiHNmSyb2X2Rn18P3rXAk7GuQzPkI+cq59aaXcL5vsg== X-Google-Smtp-Source: AGHT+IFE88Swgh/5JWzjQZ1cpizbE2cCjbwWxNJ+GGpHm7nRjaOBia46OVtz4H045Nf+mOs953pR X-Received: by 2002:a17:906:f292:b0:a52:188c:bfee with SMTP id gu18-20020a170906f29200b00a52188cbfeemr1433368ejb.58.1712821547876; Thu, 11 Apr 2024 00:45:47 -0700 (PDT) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id gh8-20020a170906e08800b00a51e45106fcsi487536ejb.1037.2024.04.11.00.45.47; Thu, 11 Apr 2024 00:45:47 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; arc=fail (body hash mismatch); spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=cubic.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 48AEB68B779; Thu, 11 Apr 2024 10:45:44 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mx0a-00172501.pphosted.com (mx0a-00172501.pphosted.com [67.231.148.188]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 17DE768B779 for ; Thu, 11 Apr 2024 10:45:35 +0300 (EEST) Received: from pps.filterd (m0215692.ppops.net [127.0.0.1]) by mx0a-00172501.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 43B0gH0C019182 for ; Thu, 11 Apr 2024 00:45:33 -0700 Received: from eur01-ve1-obe.outbound.protection.outlook.com (mail-ve1eur01lp2051.outbound.protection.outlook.com [104.47.1.51]) by mx0a-00172501.pphosted.com (PPS) with ESMTPS id 3xds7ak2rn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 11 Apr 2024 00:45:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=fDmIlauybO/E1MctELYmTkLpSt8QRu+Avo/oZSd56pn05FSfezGnvMFQCN5AC8SI3Bql9TT8MhnEj5OE861vTFCESaJOyKdo1Rqs+STJAHAaXEeSmMaPZH62nwGp0YL/bgobpY2rnbZpAZijNSAYDOzuh+K+FXHVBLU4raZupmzZy05h+JaDCj0S4RRZF6vkQmEB1tSREw1CF0knaga6f64kMQsNx24Th1y8/37HQiuN6TeYkq0WT675xWVzgH/lHrkYMDAlewEvNbhrXxXBRCFsFctR4zLa920waXRdHy4NTLu51RiHKC9j/8c6tmrI4c4UjE1WPJY8SLu+yAw4bg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=bu22z3J7x2EdebUUMOK4rxMoRGw9ylRcTEBw4O7+F7Q=; b=N8+poM6xSXVg9k9b92hmb6a/Ml8F70I7uIJvGoBACfqOUc5J0a68cJEvyPR316Ch2bpvdZLhi1RserlhG+iq5JVrrBP5183/LfxwwTulojjvL0SaMRlhuXoFNyKD2fZ+YjAxXxFkNe39fBQvvKoqczOWj3RSZanmS8T8z6J3DnIa7NEPn8qcQSONkEcVp6298Jf0xNm+8rDE/qonJ3N8EtPezkyo6z4TJMo6D3XTaxtEceysGV9voM7wtoUHxHYmHHQr+O10itqZigBDAtqhW5sWY7xNzcFznccCBJAwHLP/Rr8A1EUNtrSBal8gXoYodktOF8Ay8mZiniyDAeL2xg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=cubic.com; dmarc=pass action=none header.from=cubic.com; dkim=pass header.d=cubic.com; arc=none Received: from AS8P193MB1997.EURP193.PROD.OUTLOOK.COM (2603:10a6:20b:40d::10) by PR3P193MB0682.EURP193.PROD.OUTLOOK.COM (2603:10a6:102:31::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7409.55; Thu, 11 Apr 2024 07:45:23 +0000 Received: from AS8P193MB1997.EURP193.PROD.OUTLOOK.COM ([fe80::7a08:e115:4e52:5521]) by AS8P193MB1997.EURP193.PROD.OUTLOOK.COM ([fe80::7a08:e115:4e52:5521%3]) with mapi id 15.20.7409.053; Thu, 11 Apr 2024 07:45:20 +0000 From: =?iso-8859-2?q?Ignjatovi=E6=2C_Lazar_=28RS=29?= To: "ffmpeg-devel@ffmpeg.org" Thread-Topic: [PATCH v2] avformat: enable UDP IPv6 multicast interface selection using zone index Thread-Index: AQHai+Q0fk7SAA6ozUWLL73BXabWRw== Date: Thu, 11 Apr 2024 07:45:20 +0000 Message-ID: References: <3458953.8qv5vOS332@basile.remlab.net> In-Reply-To: <3458953.8qv5vOS332@basile.remlab.net> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: msip_labels: MSIP_Label_878f443b-b434-4a74-8e06-267f84c31196_ActionId=b5d47fee-59c1-4c88-b559-f31137eebfb3; MSIP_Label_878f443b-b434-4a74-8e06-267f84c31196_ContentBits=0; MSIP_Label_878f443b-b434-4a74-8e06-267f84c31196_Enabled=true; MSIP_Label_878f443b-b434-4a74-8e06-267f84c31196_Method=Privileged; MSIP_Label_878f443b-b434-4a74-8e06-267f84c31196_Name=Public; MSIP_Label_878f443b-b434-4a74-8e06-267f84c31196_SetDate=2024-04-11T07:45:51Z; MSIP_Label_878f443b-b434-4a74-8e06-267f84c31196_SiteId=10d6de58-a709-4821-a02c-4c46747e0059; x-ms-exchange-messagesentrepresentingtype: 1 x-ms-publictraffictype: Email x-ms-traffictypediagnostic: AS8P193MB1997:EE_|PR3P193MB0682:EE_ x-ms-office365-filtering-correlation-id: c9391965-addd-44a9-5273-08dc59fb56d5 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: ursMrbPlnfVnhMxqLJt+/xIej6U3bC1rKnXTrtWKTgp0EdeBMXN904zqnARwrBFXwrTupcoKYHqX12ZBGHd8PHSnCDyvDPgh00oyb2so3lp9Lb3iwr2NrKOeFM9YbJxCmGV8Fbz9ghybbWS0CURTk3DYR+sJwcluZN+/p3MLAucc7A0ABcEvz4sxBHBGc8PA4ipWMfIDj6xR6VN+ZFKdW6qMhl19SlsAchIdTRB+1tpsKT8WkrRcNstzfwmTiwOp8EHrxDIGU65bLITCGR7OWnkAYEDjx7UqFRA2II9LZNUn1QA2OyyXsTuf46EadsaiDDQP9+vUoY5K7Ah/plyLuYcshPJiBuJrS1HIcL5fB6/PvBtfW/1uAcz3gN0SWGqQbr8agVGzjzTFGl5FuuhZdviBqmK63Aevo8wPkj7N/NBwKw0Gqsx5R8FpXyNrJCHdwhBdZyZhcxZUWyMMY/Lc4HC8HbGLyvxT7H3v3BE7GUBk1F+mYxC9UVLHcw8BpSRFHrPZ8o6q1WsThHVGOQ7MFxC5G8pc/riQ09W2gGNlLXTdv9kRJjbBzxw2ks1CvAoWlfRzTtaO5m3CbirOleoTF+bIzlzCXsv8FuusMOlm+1S+Vy8fTj4SvL/a8JEdudPnaCViqvbEK0kDJbgRWXqsfxIiGIHxo9hys9W/iQrmMysxrc0uEgLtcazHtTR01hCNZJeyg1imDkLq6E8gH0pm2BVgzSJfn6R5iBzWwUmdOds= x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AS8P193MB1997.EURP193.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230031)(1800799015)(366007)(376005)(38070700009); DIR:OUT; SFP:1101; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?iso-8859-2?q?Csg1w0URbvCFmC6QkyuqxMA?= =?iso-8859-2?q?MRsKrdRxuYAf6R4CtfzSS5FQ/uR0By/0TUvP6a88FWqSOKVr5+LBxX8ahTpF?= =?iso-8859-2?q?tOD+hNCrc3lx3GVF6Amo3mP7iEKT/Xmmkm/G4OW6Oyea1VzCs05dimdQV59Q?= =?iso-8859-2?q?6PafhOdQB78BiqZUhvQsjaVaMWebzI2POaAUoR3i0fkBf58gfwq4qEngN2F0?= =?iso-8859-2?q?aXAlBOd1OQ5gMop6ScfBoYnXqiobqQFHOHAEc3j2znyFXwhAHAZ2Yxe0ksoi?= =?iso-8859-2?q?EoR7Eq8V6Nu9aG8AxVO49k7cUdBu5narM2Fx37HcvawGxUs7VvV94Orv5hTA?= =?iso-8859-2?q?j2qxEaH/ME4akkIflvHOFgfk9Isa3qSY5r9XY0kNaDuZVkjZgJtS6gsauknH?= =?iso-8859-2?q?R8MoAEKhPRirsPrdbTo34yF76cnwdyXvm0/B0ZPFES0HZxuDcZDg+/e+ty1N?= =?iso-8859-2?q?awSg08G35WerBuNNfV0EagCIayaZHTpe1X58tu8bW7LSimYDFT8/l1u/jxsD?= =?iso-8859-2?q?oo79txcyMAirBVnzOLYC1jF8VJKRTMXnb3FZyEbELpKg7j1ik+Oa8/YHxRHA?= =?iso-8859-2?q?KZ2Sgq0+RP7Yt1e/Vferl3vvGBrG6jXwHLa3AgqBodrMSOVgA7T2mquURV5z?= =?iso-8859-2?q?HFPAAlUsXV9i9vOXHQnIDGS7/RLI/j3CAoXXr6swpyF9IyNA5a7t5OP+/tmo?= =?iso-8859-2?q?4qkuBR0kWOE1ZvnDI/HzgE1ECOIbsmyvU1cq7EgyrpeXOZz9ob4glK1RA9mA?= =?iso-8859-2?q?5uniADj3cDO2QE/Rzv5lXRs6GDNBiVC8pq+oTnSlKuH8QB6UrRVVHuskP8NU?= =?iso-8859-2?q?xQtXA+oER/joTjbjCLOe0LkW6NmJaJAP91Q9J678LBIT7HJqy3Hee6WeQ1QT?= =?iso-8859-2?q?b54XQvMK/dXz49nL2m9rOzb62OyqfA1Qt882TW17Zw4zLFEHMg3YpbvlfabQ?= =?iso-8859-2?q?/lSAis3AVlO8emWoYtVe++jT57rAfhtULDICw7Oajff9ZB9qh0rCLAlfoFOX?= =?iso-8859-2?q?Y05+QqBogrXjta6il2Vlc7GO3Cfqe0T1IljaxuJ8ORJrOwdEZCevsWU+3P45?= =?iso-8859-2?q?bDxyQZkjBEp+3qnx1yT2tdL4I7R2Abtm1kXJ3Sx86jMn8nOTm+6MSD9RB2U0?= =?iso-8859-2?q?cqJTC2mnze3y2dC84fAvLzGzK8qyGhtl1hl2Rup8HcowORcY9ay4kg3cZ61y?= =?iso-8859-2?q?cPKN7bTjEyA/SsHHfh7UkSSbgnhs2tSlr48AACrf2UosB4F1SUAdM0mdBGgJ?= =?iso-8859-2?q?4N8x1tiwgcuMuaosFKoEMSoXM/SRVfIrJgElOL/z13/+mhy1NzdQjV9J70Kc?= =?iso-8859-2?q?Q06C39/8NrBFOJKXY6nX0kOT1YOMgFoeJZukAASJU3c5m3cw1qumKK/sKbtM?= =?iso-8859-2?q?0RfuQQx/G20Lz2uLyTnMkB+StH4cuvBQ2ksePZzk7OUO5uMqb0H6cnOwkfWH?= =?iso-8859-2?q?ZXi+p7Je6+BKydNn8Ij9JGsFpo8iDuG9dC/JDOUbxhNFwIjUtiEjE4XJoQmC?= =?iso-8859-2?q?0YQKWSOOxsek9Kmnr2qURkGRFLKxi75DbMNH17EjIb7ZTfjocc75ZnbynG/R?= =?iso-8859-2?q?tO1cORHnHzNxPS8WVmKaxTqVDCNsOblIK+DavulIt2O0VgDzx8W9+WVc=3D?= MIME-Version: 1.0 X-OriginatorOrg: cubic.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: AS8P193MB1997.EURP193.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-Network-Message-Id: c9391965-addd-44a9-5273-08dc59fb56d5 X-MS-Exchange-CrossTenant-originalarrivaltime: 11 Apr 2024 07:45:20.7623 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 10d6de58-a709-4821-a02c-4c46747e0059 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: SFA52fGxj1ieTLJPW2JiHL9c7RSk7YwJH1ICfUZRHuSb2ytJI1pIRgiTzmRUCezmD2iekfMlAV3cjS5OkSsHrw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PR3P193MB0682 X-Proofpoint-ORIG-GUID: WwhaltDpc1ewrTmVSfzSc0t6dtBHa2jO X-Proofpoint-GUID: WwhaltDpc1ewrTmVSfzSc0t6dtBHa2jO X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-04-11_02,2024-04-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 priorityscore=1501 impostorscore=0 lowpriorityscore=0 suspectscore=0 clxscore=1015 mlxscore=0 malwarescore=0 phishscore=0 spamscore=0 adultscore=0 mlxlogscore=999 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2404010003 definitions=main-2404110055 Subject: [FFmpeg-devel] [PATCH v2] avformat: enable UDP IPv6 multicast interface selection using zone index X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: bRZo3T6gy5Jj avformat: enable UDP IPv6 multicast interface selection using zone index Enabled IPv6 interface selection using zone index. Properly resolved interface index in places where default 0 interface index is used (marked with TODO: within udp.c). Adjusted binding for multicast sockets that are used for reading from the network. For mcast addresses, bind to mcast address is attempted as before. In case that this fails, which will happen on Windows, socket is bound to INADDR_ANY/IN6ADDR_ANY_INIT depending on address family. Actual interface selection is performed using udp_set_multicast_interface to point to the desired interface for sending. Closes: #368 Signed-off-by: Lazar Ignjatovic --- V1 -> V2 reverted iface resolution for IPv4 MCAST_JOIN_SOURCE_GROUP NOTE: Due to comments, this patch is proposed as one of two alternatives The other alternative uses `localaddr` for defining interfaces. configure | 3 ++ doc/protocols.texi | 2 +- libavformat/network.h | 6 +++ libavformat/udp.c | 85 +++++++++++++++++++++++++++++++++++++++---- 4 files changed, 88 insertions(+), 8 deletions(-) -- 2.41.0.windows.2 This message has been marked as Public on 04/11/2024 07:45Z. diff --git a/configure b/configure index 2a1d22310b..35d6a0b78c 100755 --- a/configure +++ b/configure @@ -2307,6 +2307,7 @@ HEADERS_LIST=" valgrind_valgrind_h windows_h winsock2_h + iphlpapi_h " INTRINSICS_LIST=" @@ -6475,6 +6476,8 @@ if ! disabled network; then check_struct winsock2.h "struct sockaddr" sa_len check_type ws2tcpip.h "struct sockaddr_in6" check_type ws2tcpip.h "struct sockaddr_storage" + check_headers iphlpapi.h -liphlpapi && network_extralibs="$network_extralibs -liphlpapi" || disable iphlpapi_h + check_func_headers iphlpapi.h GetBestInterfaceEx $network_extralibs else disable network fi diff --git a/doc/protocols.texi b/doc/protocols.texi index f54600b846..a8892845d3 100644 --- a/doc/protocols.texi +++ b/doc/protocols.texi @@ -2027,7 +2027,7 @@ packet bursts. Override the local UDP port to bind with. @item localaddr=@var{addr} -Local IP address of a network interface used for sending packets or joining +Local IPv4 address of a network interface used for sending packets or joining multicast groups. @item pkt_size=@var{size} diff --git a/libavformat/network.h b/libavformat/network.h index ca214087fc..2461b651d4 100644 --- a/libavformat/network.h +++ b/libavformat/network.h @@ -38,6 +38,10 @@ #include #include +#if HAVE_IPHLPAPI_H +#include +#endif + #ifndef EPROTONOSUPPORT #define EPROTONOSUPPORT WSAEPROTONOSUPPORT #endif @@ -64,6 +68,8 @@ int ff_neterrno(void); #include #include #include +#include +#include #define ff_neterrno() AVERROR(errno) #endif /* HAVE_WINSOCK2_H */ diff --git a/libavformat/udp.c b/libavformat/udp.c index d9514f5026..00c73f9ec9 100644 --- a/libavformat/udp.c +++ b/libavformat/udp.c @@ -35,6 +35,7 @@ #include "libavutil/opt.h" #include "libavutil/log.h" #include "libavutil/time.h" +#include "libavutil/avstring.h" #include "internal.h" #include "network.h" #include "os_support.h" @@ -220,8 +221,7 @@ static int udp_join_multicast_group(int sockfd, struct sockaddr *addr, struct ipv6_mreq mreq6; memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); - //TODO: Interface index should be looked up from local_addr - mreq6.ipv6mr_interface = 0; + mreq6.ipv6mr_interface = ((struct sockaddr_in6 *)addr)->sin6_scope_id; if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { ff_log_net_error(logctx, AV_LOG_ERROR, "setsockopt(IPV6_ADD_MEMBERSHIP)"); return ff_neterrno(); @@ -231,6 +231,39 @@ static int udp_join_multicast_group(int sockfd, struct sockaddr *addr, return 0; } +static int udp_set_multicast_interface(int sockfd, struct sockaddr *addr, + struct sockaddr *local_addr, void *logctx) +{ +#ifdef IP_MULTICAST_IF + if (addr->sa_family == AF_INET) { + struct ip_mreq mreq; + + mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr; + if (local_addr) + mreq.imr_interface = ((struct sockaddr_in *)local_addr)->sin_addr; + else + mreq.imr_interface.s_addr = INADDR_ANY; + + if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_IF, (const void *)&mreq, sizeof(mreq)) < 0) { + ff_log_net_error(logctx, AV_LOG_ERROR, "setsockopt(IP_MULTICAST_IF)"); + return ff_neterrno(); + } + } +#endif +#if defined(IPV6_MULTICAST_IF) && defined(IPPROTO_IPV6) + if (addr->sa_family == AF_INET6) { + unsigned int iface; + iface = ((struct sockaddr_in6 *)addr)->sin6_scope_id; + + if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &iface, sizeof(unsigned int)) < 0) { + ff_log_net_error(logctx, AV_LOG_ERROR, "setsockopt(IPV6_MULTICAST_IF)"); + return ff_neterrno(); + } + } +#endif + return 0; +} + static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr, struct sockaddr *local_addr, void *logctx) { @@ -254,8 +287,7 @@ static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr, struct ipv6_mreq mreq6; memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); - //TODO: Interface index should be looked up from local_addr - mreq6.ipv6mr_interface = 0; + mreq6.ipv6mr_interface = ((struct sockaddr_in6 *)addr)->sin6_scope_id; if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { ff_log_net_error(logctx, AV_LOG_ERROR, "setsockopt(IPV6_DROP_MEMBERSHIP)"); return -1; @@ -284,6 +316,9 @@ static int udp_set_multicast_sources(URLContext *h, //TODO: Interface index should be looked up from local_addr mreqs.gsr_interface = 0; + if (level == IPPROTO_IPV6) + mreqs.gsr_interface = ((struct sockaddr_in6 *)addr)->sin6_scope_id; + memcpy(&mreqs.gsr_group, addr, addr_len); memcpy(&mreqs.gsr_source, &sources[i], sizeof(*sources)); @@ -340,9 +375,24 @@ static int udp_set_url(URLContext *h, { struct addrinfo *res0; int addr_len; + const char *host, *sc; + char address[1024], scope[1024]; - res0 = ff_ip_resolve_host(h, hostname, port, SOCK_DGRAM, AF_UNSPEC, 0); + if (sc = strchr(hostname, '%')) { + av_strlcpy(address, hostname, FFMIN(1024, sc - hostname + 1)); + av_strlcpy(scope, sc + 1, FFMIN(1024, strlen(hostname) - (sc - hostname))); + host = address; + } else { + host = hostname; + } + + res0 = ff_ip_resolve_host(h, host, port, SOCK_DGRAM, AF_UNSPEC, 0); if (!res0) return AVERROR(EIO); +#if HAVE_IPHLPAPI_H || !HAVE_WINSOCK2_H + if (res0->ai_family== AF_INET6 && strlen(scope) > 0) { + ((struct sockaddr_in6*)res0->ai_addr)->sin6_scope_id = if_nametoindex(scope); + } +#endif memcpy(addr, res0->ai_addr, res0->ai_addrlen); addr_len = res0->ai_addrlen; freeaddrinfo(res0); @@ -841,8 +891,23 @@ static int udp_open(URLContext *h, const char *uri, int flags) if (s->is_multicast && (h->flags & AVIO_FLAG_READ)) { bind_ret = bind(udp_fd,(struct sockaddr *)&s->dest_addr, len); } - /* bind to the local address if not multicast or if the multicast - * bind failed */ + + /* bind to ADDR_ANY if the multicast bind failed */ + if (s->is_multicast && bind_ret < 0) { + struct addrinfo *res; + + if (s->dest_addr.ss_family == AF_INET) + res = ff_ip_resolve_host(h, "0.0.0.0", 0, SOCK_DGRAM, AF_UNSPEC, 0); + else if (s->dest_addr.ss_family == AF_INET6) + res = ff_ip_resolve_host(h, "::", 0, SOCK_DGRAM, AF_UNSPEC, 0); + + if (res && res->ai_addr) { + bind_ret = bind(udp_fd, res->ai_addr, res->ai_addrlen); + } + + freeaddrinfo(res); + } + /* the bind is needed to give a port to the socket now */ if (bind_ret < 0 && bind(udp_fd,(struct sockaddr *)&my_addr, len) < 0) { ff_log_net_error(h, AV_LOG_ERROR, "bind failed"); @@ -855,6 +920,12 @@ static int udp_open(URLContext *h, const char *uri, int flags) s->local_port = udp_port(&my_addr, len); if (s->is_multicast) { + if ((ret = udp_set_multicast_interface(udp_fd, + (struct sockaddr *)&s->dest_addr, + (struct sockaddr *)&s->local_addr_storage, + h)) < 0) + goto fail; + if (h->flags & AVIO_FLAG_WRITE) { /* output */ if ((ret = udp_set_multicast_ttl(udp_fd, s->ttl, (struct sockaddr *)&s->dest_addr, h)) < 0)