I create an UDP socket with the Socket module and version: 6. I want it to listen only to IPv6 (by default, version: 6 listens on both v4 and v6). Erlang's inet module has a ipv6_v6only option but I don't know how to use it when using Elixir's Socket module. Calling :inet.setopts/2 after the call to Socket.UDP.open/2 always produce a {:error, :einval}. Any code example?
(I know I can do it by tuning the net.ipv6.bindv6only sysctl on Linux but I would prefer a solution that does not require to be root.)
Socket.UDP.open/2 is effectively routed to :gen_udp.open/2 which accepts a keyword of type open_option() as a second argument, which is in turn an extended type option().
Somewhat alongside the following would do
Socket.UDP.socket(port, version: 6)
This could have been easily seen from the arguments/1 implementation I’ve linked above.
Related
A simple experiment in python (on Windows) shows that I am able to bind to the same port on both the wildcard address and a specific address simultaneously:
import socket
import select
MY_PORT = 13337
sany = socket.socket()
sany.bind(('', MY_PORT))
sany.listen(0)
sloc = socket.socket()
sloc.bind(('127.0.0.1', MY_PORT))
sloc.listen(0)
socks = [sany, sloc]
ready, _, _ = select.select(socks, [], [])
print socks.index(ready[0])
Conceptually, they overlap in what they're supposed to cover. Continuing the experiment by connecting to ('127.0.0.1', 13337) from a different prompt indicates that the more specific socket 'wins' (i.e. 1 is printed).
I'm seeing similar behavior in SOCK_DGRAM sockets.
My questions are as follows:
Is this behavior somehow contractual (Winsock, Berkeley Sockets, etc.)?
How should this behave for multicast sockets?
How should this behave on *nix systems?
What you describe is possible on Windows Server 2003 and later, but only when the two bind() calls are made by the same user account:
Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE
Enhanced socket security was added with the release of Windows Server 2003. In previous Microsoft server operating system releases, the default socket security easily allowed processes to hijack ports from unsuspecting applications. In Windows Server 2003, sockets are not in a sharable state by default. Therefore, if an application wants to allow other processes to reuse a port on which a socket is already bound, it must specifically enable it. If that is the case, the first socket to call bind on the port must have SO_REUSEADDR set on the socket. The only exception to this case occurs when the second bind call is performed by the same user account that made the original call to bind. This exception exists solely to provide backward compatibility.
The table below describes the behavior that occurs in Windows Server 2003 and later operating systems when a second socket attempts to bind to an address previously bound to by a first socket using specific socket options.
...
The socket binding behavior changes when the socket bind calls are made under different user accounts. The table below specifies the behavior that occurs in Windows Server 2003 and later operating systems when a second socket attempts to bind to an address previously bound to by a first socket using specific socket options and a different user account.
In earlier Windows versions, the behavior was different:
The table below describes the behavior that occurs in Windows XP and earlier when a second socket attempts to bind to an address previously bound to by a first socket using specific socket options.
...
In the case where the first call to bind sets either SO_REUSEADDR or no socket options at all, the second bind call will "hijack" the port and the application will be unable to determine which of the two sockets received specific packets sent to the "shared" port.
I need to upgrade a Windows Kernel Mode Driver from IPV4 to IPV4/IPV6 but the existing kernel mode socket library which uses TDI does not support IPV6.
So I would like to change the socket library to "Winsock Kernel" http://msdn.microsoft.com/en-us/library/windows/hardware/ff571084(v=vs.85).aspx
Note: This is not winsock2.
I started making the necessary modifications to use WSK instead of Kernsock from Storagecraft but there is a lot to consider given that this driver code runs on both windows and linux.
I am wondering if there is a kernel mode socket wrapper around WSK available, preferably with BSD or winsock2 function API signatures. My searches do not yield anything.
Thanks.
I found one UDP code project which seems to provide most of what I need.
I thought I would post it here for anyone else who needs a WSK wrapper.
Project:
https://code.google.com/p/wskudp/
UDP Source:
https://code.google.com/p/wskudp/source/browse/#svn%2Ftrunk%2Fwskudp
TCP Source:
https://code.google.com/p/wskudp/source/browse/#svn%2Ftrunk%2Fwsktcp
Thanks to https://code.google.com/u/x86ddk/ for creating the project.
NOTE: I haven't tested this yet.
I am using setsocketopt function for Ipv4 address and using IP_TOS value for PPROTO_IP option.
what is the equivalent of IP_TOS in IPv6 addressing?
In IPv6 we use PROTO_IPv6, but I could not find any equivalent option like IP_TOS in IPv6 addressing.
I don't know how widely supported it is, but I believe the constant for "setsockopt() traffic class" would be IPV6_TCLASS:
http://www.ietf.org/rfc/rfc3542.txt
See also:
http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.commtechref/doc/commtrf2/setsockopt.htm
http://developer.android.com/reference/java/net/SocketOptions.html
As per MSDN Article ID: 248611 ToS is ignored and the GQOS API is limited to IPv4-only. For IPv6 and IPv4 you must use qWAVE QOS which requires Vista or later platforms.
i.e. QoS is completely abstracted away from BSD sockets in Windows land.
Deprecating old QoS APIs
"Back in XP we had disabled the Winsock IP_TOS option. If you used this socket option, the call would succeed but be ignored silently. You could re-enable it through a registry value. In Vista, this registry mechanism has been removed: Winsock IP_TOS option is no longer available."
Setup:
I have client C connecting to server S
Both C and S are on the same machine
In C the server address is hardcoded to 127.0.0.1. Likewise, in S the client address is hardcoded to 127.0.0.1
Problem:
I want to be able to sniff the traffic between the client and the server.
Due to the configuration, I cannot move the client nor the server to different locations (the address are hardcoded)
Installing the loopback interface and using tools like Wireshark+WinPcap doesn't lead anywhere (was actually already known but was worth a try)
RawCap, suggested in another topic, doesn't work. IP 127.0.0.1 is listed, but does not record any traffic.
Using rinetd to route the traffic elsewhere, as suggested here doesn't work (cannot bind on 127.0.0.1)
Not interested in using a HTTP local proxy, such as Fiddler, because I'd like to capture also other protocols
Two commercial tools work, specifically CommView and Local Network Monitor, which means it must be possible to do that ;)
How can I do to capture the traffic?
Any pointer on functions I should use or documentation I should read?
Thanks!
Basically you need to write a TDI filter driver to achieve that... for some pointers see:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff565685%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/hardware/ff563317%28v=VS.85%29.aspx
Another option is to write a WinSock LSP.
BEWARE
Since Windows 8 it is strongly encouraged to use WFP (Windows Filtering Platform) for this sort of thing...
Although it might be more cost-effective to just use/buy an existing solution - esp. if you are not a very experienced driver developer...
Use RawCap, which can solve your concerns, see this
I am implementing dual stack mode to support IPv4 and IPv6.
If I am creating a IPv6 socket and listening on it, will it accept the connection from IPv4 socket also ??
Yes, unless the operating system is configured otherwise, e.g. net.ipv6.bindv6only=1 in Linux, or you set the IPV6_V6ONLY socket option.
Only if the system has a dual-stack implementation. Most modern systems do, but old versions of Windows and OpenBSD do not. You shouldn't rely on this though. Get the value of the IPV6_V6ONLY socket option and if it's zero you will need to open a second socket for IPv4.
When using a dual-stack socket IPv4 addresses are represented as ::ffff:[IPv4 address]; for example ::ffff:127.0.0.1 (this corresponds to ::ffff:7f00:1; it's just typically printed in dot-decimal notation for the sake of readability).
According to Microsoft, the default even in dual stack mode is to have IPV6_V6ONLY set to false - but you can enable it through the setsockopt(2) call. FWIW, "Old versions" of Windows (single-stack) include the still-widely-used Windows XP (anything older than Vista).
So, if you're on Windows you should try and disable IPV6_V6ONLY and see if it succeeds. I don't know if that's a good answer for other single-stack implementations or not.