Я имел взглянуть на код в bitcoinrpc.cpp, в частности, функции StartRPCThreads ().
Код пытается открыть сокет IPv6, а затем установить опцию «v6_only» ложь, если используется опция «rpcallowip». Это должно привести сокет для прослушивания соединений IPv4, но на моей системе NetStat не показывает сокет прослушивания IPv4 (см мой оригинальный пост).
Если сокет не удалось открыть, или вариант «rpcallowip» не используется, код открывает отдельный сокет IPv4. Это означает, что, когда «rpcallowip» не используется, отдельные IPv4 и IPv6 сокеты всегда используются.
Когда я изменить код (путем установки
fListening ложь), так что он пытается открыть сокет IPv4 после открытия сокета IPv4 / IPv6, я получаю ошибку:
Ошибка: Произошла ошибка при настройке RPC порт 8332 для прослушивания на IPv4: Адрес уже используетсякоторый указывает на то, что комбинированный разъем IPv4 / IPv6 слушает, хотя NetStat не показывает это.
Когда я изменить код (заставляя
set_option (v6_only (правда)) и удаление
если (! fListening ...) линия), так что он всегда открывает отдельные IPv4 и IPv6 сокеты, все работает, как я ожидать, что они:
пользователь @ сервер: ~ $ NetStat -LP | Grep bitcoind
ТСР 0 0 *: 8332 *: * LISTEN 3063 / bitcoind
ТСР 0 0 *: 8333 *: * LISTEN 3063 / bitcoind
tcp6 0 0 [::]: 8332 [::]: * СЛУШАТЬ 3063 / bitcoind
tcp6 0 0 [::]: 8333 [::]: * СЛУШАТЬ 3063 / bitcoind
Я предполагаю, что сокет IPv4 / IPv6 просто работает на большинстве систем. К сожалению, я не могу увидеть работы вокруг систем, как у меня без перекомпиляции bitcoind.
Вот изменения, которые я сделал:
Diff --git а / SRC / bitcoinrpc.cpp б / SRC / bitcoinrpc.cpp
Индекс c99b74f..ba7f462 100644
--- а / SRC / bitcoinrpc.cpp
+++ б / SRC / bitcoinrpc.cpp
@@ -791,8 +791,8 @@ StartRPCThreads недействительными ()
acceptor->открытый (endpoint.protocol ());
acceptor->set_option (повышение :: ASIO :: IP :: Tcp :: акцепторный :: reuse_address (истина));
- // Попробуйте сделать сокет двойной IPv6 / IPv4 (при прослушивании на "Любые" адрес)
- acceptor->set_option (повышение :: ASIO :: IP :: v6_only (замыкания на себя), v6_only_error);
+ // Это только IPv6 сокет
+ acceptor->set_option (повышение :: ASIO :: IP :: v6_only (истина), v6_only_error);
acceptor->связывания (конечная точка);
acceptor->слушать (socket_base :: max_connections);
@@ -807,8 +807,7 @@ StartRPCThreads недействительными ()
}
пытаться {
- // Если двойной IPv6 / IPv4 не удалось (или мы открываем петлевые интерфейсы только), открытый IPv4 отдельно
- если (! fListening || петлевой || v6_only_error)
+ // Это сокет IPv4
{
BindAddress = шлейф? ASIO :: IP :: address_v4 :: петлевой (): ASIO :: IP :: address_v4 :: любой ();
endpoint.address (BindAddress);