Dave Nottage 557 Posted December 27, 2019 (edited) I was originally using some Indy code, however I figured I strip back the code to the absolute basics in order to try and find out what is going wrong. This is the result: uses Posix.SysSocket, Posix.NetinetIn, Posix.ArpaInet; const // IPv6 address of en0 on my Mac cIPv6 = 'fe80::ca9:418d:c487:cba'; cPort = 9099; procedure TForm1.Button1Click(Sender: TObject); var LHandle, LOption, LError: Integer; LSockAddrIPv6: sockaddr_in6; LNetAddrIPv6: in6_addr; LMarshaller: TMarshaller; LMsg: string; begin LHandle := socket(AF_INET6, SOCK_DGRAM, 0); if LHandle > 0 then begin LOption := 1; if setsockopt(LHandle, SOL_SOCKET, SO_REUSEADDR, LOption, SizeOf(LOption)) = 0 then begin if inet_pton(AF_INET6, LMarshaller.AsAnsi(cIPv6).ToPointer, @LNetAddrIPv6) = 1 then begin FillChar(LSockAddrIPv6, SizeOf(LSockAddrIPv6), 0); LSockAddrIPv6.sin6_len := SizeOf(LSockAddrIPv6); LSockAddrIPv6.sin6_family := AF_INET6; LSockAddrIPv6.sin6_addr := LNetAddrIPv6; LSockAddrIPv6.sin6_port := htons(cPort); if bind(LHandle, PSockAddr(@LSockAddrIPv6)^, SizeOf(LSockAddrIPv6)) = -1 then begin LError := GetLastError; ShowMessage(SysErrorMessage(LError)); end; end; end; end; end; The bind fails, however I'm yet to be able to ascertain why. The error code returned in LError is 49, which apparently equates to: "Can't assign requested address". Any ideas on what the problem might be? The same code also fails on iOS (using a valid IPv6 address), so is it perhaps an Apple thing? Edited December 27, 2019 by Dave Nottage Share this post Link to post
Dave Nottage 557 Posted December 27, 2019 I've finally discovered the problem: The sin6_scope_id member of LSockAddrIPv6 needed to be set to the index of the interface that has the address. Share this post Link to post
Sherlock 663 Posted December 27, 2019 6 hours ago, Dave Nottage said: I've finally discovered the problem: The sin6_scope_id member of LSockAddrIPv6 needed to be set to the index of the interface that has the address. And what does that line look like? 1 Share this post Link to post
Dave Nottage 557 Posted December 28, 2019 16 hours ago, Sherlock said: And what does that line look like? The simplified version (as per the example) would look like this: LSockAddrIPv6.sin6_scope_id = 4; Because the index of the interface in question is 4. I've been working on some "home grown" (i.e. not Indy) code that includes retrieving the local addresses and interface indexes so that they can be used for this kind of thing (amongst others). The purpose is to have a reliable, functional means of advertising that works on all platforms, using IPv4, IPv6 and works on IPv6 only networks. I've diverged from Indy because I was having to jump through too many hoops in order to make it all work, and to simplify everything. I plan on publishing the code when it is complete. 1 Share this post Link to post