Basic support for IPv6
parent
577f6c7861
commit
9f0503a24b
|
@ -787,7 +787,7 @@ void RTMPPublisher::BeginPublishing()
|
|||
void LogInterfaceType (RTMP *rtmp)
|
||||
{
|
||||
MIB_IPFORWARDROW route;
|
||||
DWORD destAddr;
|
||||
DWORD destAddr, sourceAddr;
|
||||
CHAR hostname[256];
|
||||
|
||||
if (rtmp->Link.hostname.av_len >= sizeof(hostname)-1)
|
||||
|
@ -802,7 +802,14 @@ void LogInterfaceType (RTMP *rtmp)
|
|||
|
||||
destAddr = *(DWORD *)h->h_addr_list[0];
|
||||
|
||||
if (!GetBestRoute (destAddr, rtmp->m_bindIP.addr.sin_addr.S_un.S_addr, &route))
|
||||
if (rtmp->m_bindIP.addrLen == 0)
|
||||
sourceAddr = 0;
|
||||
else if (rtmp->m_bindIP.addr.ss_family == AF_INET)
|
||||
sourceAddr = (*(struct sockaddr_in *)&rtmp->m_bindIP).sin_addr.S_un.S_addr;
|
||||
else
|
||||
return; // getting route for IPv6 is far more complex, ignore for now
|
||||
|
||||
if (!GetBestRoute (destAddr, sourceAddr, &route))
|
||||
{
|
||||
MIB_IFROW row;
|
||||
zero (&row, sizeof(row));
|
||||
|
@ -1041,9 +1048,14 @@ DWORD WINAPI RTMPPublisher::CreateConnectionThread(RTMPPublisher *publisher)
|
|||
if (scmp(strBindIP, TEXT("Default")))
|
||||
{
|
||||
Log(TEXT(" Binding to non-default IP %s"), strBindIP.Array());
|
||||
rtmp->m_bindIP.addr.sin_family = AF_INET;
|
||||
|
||||
if (schr(strBindIP.Array(), ':'))
|
||||
rtmp->m_bindIP.addr.ss_family = AF_INET6;
|
||||
else
|
||||
rtmp->m_bindIP.addr.ss_family = AF_INET;
|
||||
rtmp->m_bindIP.addrLen = sizeof(rtmp->m_bindIP.addr);
|
||||
if (WSAStringToAddress(strBindIP.Array(), AF_INET, NULL, (LPSOCKADDR)&rtmp->m_bindIP.addr, &rtmp->m_bindIP.addrLen) == SOCKET_ERROR)
|
||||
|
||||
if (WSAStringToAddress(strBindIP.Array(), rtmp->m_bindIP.addr.ss_family, NULL, (LPSOCKADDR)&rtmp->m_bindIP.addr, &rtmp->m_bindIP.addrLen) == SOCKET_ERROR)
|
||||
{
|
||||
// no localization since this should rarely/never happen
|
||||
failReason = TEXT("WSAStringToAddress: Could not parse address");
|
||||
|
|
|
@ -484,49 +484,48 @@ INT_PTR SettingsAdvanced::ProcMessage(UINT message, WPARAM wParam, LPARAM lParam
|
|||
|
||||
//------------------------------------
|
||||
|
||||
MIB_IPADDRTABLE tempTable;
|
||||
DWORD dwSize = 0;
|
||||
if (GetIpAddrTable (&tempTable, &dwSize, TRUE) == ERROR_INSUFFICIENT_BUFFER)
|
||||
IP_ADAPTER_ADDRESSES *ipTable;
|
||||
|
||||
DWORD dwSize = 65536;
|
||||
ipTable = (IP_ADAPTER_ADDRESSES *)Allocate(dwSize);
|
||||
|
||||
DWORD flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER;
|
||||
|
||||
hwndTemp = GetDlgItem(hwnd, IDC_BINDIP);
|
||||
SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("Default"));
|
||||
|
||||
if (!GetAdaptersAddresses(AF_UNSPEC, flags, NULL, ipTable, &dwSize))
|
||||
{
|
||||
PMIB_IPADDRTABLE ipTable;
|
||||
IP_ADAPTER_ADDRESSES *pCurrAddresses = ipTable;
|
||||
|
||||
ipTable = (PMIB_IPADDRTABLE)Allocate(dwSize);
|
||||
|
||||
if (GetIpAddrTable (ipTable, &dwSize, TRUE) == NO_ERROR)
|
||||
while (pCurrAddresses)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
hwndTemp = GetDlgItem(hwnd, IDC_BINDIP);
|
||||
SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("Default"));
|
||||
|
||||
for (i=0; i < ipTable->dwNumEntries; i++)
|
||||
if (pCurrAddresses->OperStatus == IfOperStatusUp && pCurrAddresses->IfType != IF_TYPE_SOFTWARE_LOOPBACK)
|
||||
{
|
||||
String strAddress;
|
||||
DWORD strLength = 32;
|
||||
|
||||
// don't allow binding to localhost
|
||||
if ((ipTable->table[i].dwAddr & 0xFF) == 127)
|
||||
continue;
|
||||
|
||||
strAddress.SetLength(strLength);
|
||||
|
||||
SOCKADDR_IN IP;
|
||||
|
||||
IP.sin_addr.S_un.S_addr = ipTable->table[i].dwAddr;
|
||||
IP.sin_family = AF_INET;
|
||||
IP.sin_port = 0;
|
||||
zero(&IP.sin_zero, sizeof(IP.sin_zero));
|
||||
|
||||
WSAAddressToString ((LPSOCKADDR)&IP, sizeof(IP), NULL, strAddress.Array(), &strLength);
|
||||
SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)strAddress.Array());
|
||||
PIP_ADAPTER_UNICAST_ADDRESS pUnicast = pCurrAddresses->FirstUnicastAddress;
|
||||
while (pUnicast)
|
||||
{
|
||||
if (pUnicast->Address.lpSockaddr->sa_family == AF_INET || pUnicast->Address.lpSockaddr->sa_family == AF_INET6)
|
||||
{
|
||||
TCHAR friendlyAddress[256];
|
||||
DWORD friendlyAddressLen = _countof(friendlyAddress);
|
||||
if (!WSAAddressToString(pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength, NULL, friendlyAddress, &friendlyAddressLen))
|
||||
{
|
||||
SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)friendlyAddress);
|
||||
}
|
||||
}
|
||||
pUnicast = pUnicast->Next;
|
||||
}
|
||||
}
|
||||
|
||||
LoadSettingComboString(hwndTemp, TEXT("Publish"), TEXT("BindToIP"), TEXT("Default"));
|
||||
pCurrAddresses = pCurrAddresses->Next;
|
||||
}
|
||||
|
||||
Free(ipTable);
|
||||
}
|
||||
|
||||
LoadSettingComboString(hwndTemp, TEXT("Publish"), TEXT("BindToIP"), TEXT("Default"));
|
||||
|
||||
//need this as some of the dialog item sets above trigger the notifications
|
||||
ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_HIDE);
|
||||
SetChangedSettings(invalidSettings);
|
||||
|
|
|
@ -1087,7 +1087,7 @@ int RTMP_SetupURL2(RTMP *r, char *url, char *playpath)
|
|||
}
|
||||
|
||||
static int
|
||||
add_addr_info(struct sockaddr_in *service, AVal *host, int port)
|
||||
add_addr_info(struct sockaddr_storage *service, AVal *host, int port)
|
||||
{
|
||||
char *hostname;
|
||||
int ret = TRUE;
|
||||
|
@ -1102,20 +1102,50 @@ add_addr_info(struct sockaddr_in *service, AVal *host, int port)
|
|||
hostname = host->av_val;
|
||||
}
|
||||
|
||||
service->sin_addr.s_addr = inet_addr(hostname);
|
||||
if (service->sin_addr.s_addr == INADDR_NONE)
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *result = NULL;
|
||||
struct addrinfo *ptr = NULL;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
service->ss_family = AF_UNSPEC;
|
||||
|
||||
char portStr[8];
|
||||
|
||||
itoa(port, portStr, 10);
|
||||
|
||||
int err = getaddrinfo(hostname, portStr, &hints, &result);
|
||||
|
||||
if (err)
|
||||
{
|
||||
struct hostent *host = gethostbyname(hostname);
|
||||
if (host == NULL || host->h_addr == NULL)
|
||||
{
|
||||
RTMP_Log(RTMP_LOGERROR, "Problem accessing the DNS. (addr: %s, error: %d)", hostname, GetSockError());
|
||||
ret = FALSE;
|
||||
goto finish;
|
||||
}
|
||||
service->sin_addr = *(struct in_addr *)host->h_addr;
|
||||
RTMP_Log(RTMP_LOGERROR, "Could not resolve %s: %s (%d)", hostname, gai_strerrorA(GetSockError()), GetSockError());
|
||||
ret = FALSE;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
// they should come back in OS preferred order
|
||||
for (ptr = result; ptr != NULL; ptr = ptr->ai_next)
|
||||
{
|
||||
if (ptr->ai_family == AF_INET || ptr->ai_family == AF_INET6)
|
||||
{
|
||||
memcpy(service, ptr->ai_addr, ptr->ai_addrlen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
freeaddrinfo(result);
|
||||
|
||||
if (service->ss_family == AF_UNSPEC)
|
||||
{
|
||||
RTMP_Log(RTMP_LOGERROR, "Could not resolve server '%s': no valid address found", hostname);
|
||||
ret = FALSE;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
service->sin_port = htons(port);
|
||||
finish:
|
||||
if (hostname != host->av_val)
|
||||
free(hostname);
|
||||
|
@ -1132,7 +1162,7 @@ RTMP_Connect0(RTMP *r, struct sockaddr * service)
|
|||
|
||||
//best to be explicit, we need overlapped socket
|
||||
//r->m_sb.sb_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
r->m_sb.sb_socket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
|
||||
r->m_sb.sb_socket = WSASocket(service->sa_family, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
|
||||
|
||||
if (r->m_sb.sb_socket != -1)
|
||||
{
|
||||
|
@ -1148,7 +1178,7 @@ RTMP_Connect0(RTMP *r, struct sockaddr * service)
|
|||
}
|
||||
}
|
||||
|
||||
if (connect(r->m_sb.sb_socket, service, sizeof(struct sockaddr)) < 0)
|
||||
if (connect(r->m_sb.sb_socket, service, sizeof(struct sockaddr_storage)) < 0)
|
||||
{
|
||||
int err = GetSockError();
|
||||
if (err == 10061)
|
||||
|
@ -1274,7 +1304,7 @@ int
|
|||
RTMP_Connect(RTMP *r, RTMPPacket *cp)
|
||||
{
|
||||
HOSTENT *h;
|
||||
struct sockaddr_in service;
|
||||
struct sockaddr_storage service;
|
||||
if (!r->Link.hostname.av_len)
|
||||
return FALSE;
|
||||
|
||||
|
@ -1286,8 +1316,7 @@ RTMP_Connect(RTMP *r, RTMPPacket *cp)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
memset(&service, 0, sizeof(struct sockaddr_in));
|
||||
service.sin_family = AF_INET;
|
||||
memset(&service, 0, sizeof(service));
|
||||
|
||||
if (r->Link.socksport)
|
||||
{
|
||||
|
@ -1314,11 +1343,16 @@ static int
|
|||
SocksNegotiate(RTMP *r)
|
||||
{
|
||||
unsigned long addr;
|
||||
struct sockaddr_in service;
|
||||
memset(&service, 0, sizeof(struct sockaddr_in));
|
||||
struct sockaddr_storage service;
|
||||
memset(&service, 0, sizeof(service));
|
||||
|
||||
add_addr_info(&service, &r->Link.hostname, r->Link.port);
|
||||
addr = htonl(service.sin_addr.s_addr);
|
||||
|
||||
// not doing IPv6 socks
|
||||
if (service.ss_family == AF_INET6)
|
||||
return FALSE;
|
||||
|
||||
addr = htonl((*(struct sockaddr_in *)&service).sin_addr.s_addr);
|
||||
|
||||
{
|
||||
char packet[] =
|
||||
|
|
|
@ -243,7 +243,7 @@ extern "C"
|
|||
|
||||
typedef struct RTMP_BINDINFO
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
struct sockaddr_storage addr;
|
||||
int addrLen;
|
||||
} RTMP_BINDINFO;
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <Mstcpip.h>
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
|
|
Loading…
Reference in New Issue