Henrik Goldman wrote:
> Only the ipv6 socket complains with errno 22.
consult header errno.h or use function perror/strerror
This is a discussion on ipv6 accept() on AIX 5.1 - Aix ; Hi, Within our software we've added IPv6 support since it consist of a tcp client and server application. This functionality seems to work fine on other operating systems but not on AIX. On the server side the socket handling is ...
Hi,
Within our software we've added IPv6 support since it consist of a tcp
client and server application.
This functionality seems to work fine on other operating systems but not on
AIX.
On the server side the socket handling is written as a dual-stack ipv4 and
ipv6 interface. This means that we've called the usual socket/bind/listen
for both ipv4 and ipv6.
Once we hit accept() we end up with a errno 22 on the ipv6 socket. From what
I could see this refers to invalid parameter.
struct sockaddr_storage ClientAddr;
SOCKET_LEN nAddrLen = sizeof(ClientAddr);
SOCKET RemoteClientSocket;
// First we try IPv4
RemoteClientSocket = accept(m_ListenSocket4.GetSocket(), (struct sockaddr *)
&ClientAddr, &nAddrLen);
// Then we try IPv6
if (RemoteClientSocket == INVALID_SOCKET)
{
if (m_ListenSocket6.GetSocket() != INVALID_SOCKET)
RemoteClientSocket = accept(m_ListenSocket6.GetSocket(), (struct sockaddr *)
&ClientAddr, &nAddrLen);
}
.....
Only the ipv6 socket complains with errno 22.
Can anyone give some insight on this?
Thanks.
-- Henrik
Henrik Goldman wrote:
> Only the ipv6 socket complains with errno 22.
consult header errno.h or use function perror/strerror
> consult header errno.h or use function perror/strerror
That is the easy part. I already did that. The error refers to invalid
argument. However I still question how this can happen when the same code
works on other platforms. Maybe there is something obvious I've overlooked
but I could not find any examples from IBM on IPv6 socket code.
-- Henrik
Henrik Goldmanwrote:
> Once we hit accept() we end up with a errno 22 on the ipv6
> socket. From what I could see this refers to invalid parameter.
> struct sockaddr_storage ClientAddr;
> SOCKET_LEN nAddrLen = sizeof(ClientAddr);
> SOCKET RemoteClientSocket;
^^^^^^
Trying to also have this on Windows?-)
> // First we try IPv4
> RemoteClientSocket = accept(m_ListenSocket4.GetSocket(), (struct sockaddr *)
> &ClientAddr, &nAddrLen);
> // Then we try IPv6
> if (RemoteClientSocket == INVALID_SOCKET)
> {
> if (m_ListenSocket6.GetSocket() != INVALID_SOCKET)
> RemoteClientSocket = accept(m_ListenSocket6.GetSocket(), (struct sockaddr *)
> &ClientAddr, &nAddrLen);
> }
Have you tried a system call trace to see exactly what is being passed
to accept() for the IPv6 socket? Any chance the previous accept()
call against the IPv4 endpoint has set the values to something not
well liked for an IPv6 socket?
rick jones
--
denial, anger, bargaining, depression, acceptance, rebirth...
where do you want to be today?
these opinions are mine, all mine; HP might not want them anyway...
feel free to post, OR email to rick.jones2 in hp.com but NOT BOTH...
>> SOCKET RemoteClientSocket;
> ^^^^^^
> Trying to also have this on Windows?-)
Sorry about that. This is a Windows define which I carefully define manually
on AIX. Essentially this is an int as it should be.
> Have you tried a system call trace to see exactly what is being passed
> to accept() for the IPv6 socket? Any chance the previous accept()
> call against the IPv4 endpoint has set the values to something not
> well liked for an IPv6 socket?
>
Are there any tools to do that with?
I think a few experiements could be needed which I did not yet have time
for. E.g. what if the IPv6 socket was polled first? What if I used a setopt
flag to ensure that the ipv6 socket would only be locked to the IPv6
protocol. To the best of my knowledge this is how dual stack implementations
should be done.
Other examples usually have an array of 2 sockets instead which is passed to
accept one at a time.
-- Henrik
Henrik Goldmanwrote:
> >> SOCKET RemoteClientSocket;
> > ^^^^^^
> > Trying to also have this on Windows?-)
> Sorry about that. This is a Windows define which I carefully define
> manually on AIX. Essentially this is an int as it should be.
No need to be sorry, netperf has that too
> > Have you tried a system call trace to see exactly what is being
> > passed to accept() for the IPv6 socket? Any chance the previous
> > accept() call against the IPv4 endpoint has set the values to
> > something not well liked for an IPv6 socket?
> Are there any tools to do that with?
Well, if you were running Linux I would say use strace. If you were
running HP-UX I would say use tusc. As for AIX, I would think there
is a system call trace tool, but I'm not familiar with it. I may have
run one once or twice while porting netperf, but cannot remember the
name at the moment.
If all else fails, you could use stone knives and bearskins - add a
printf (sorry I speak C not C++before/after each accept() call to
display the values of those parameters
> Other examples usually have an array of 2 sockets instead which is
> passed to accept one at a time.
Um, who's "accept()" takes an array of fd's? Do you mean some other,
extended accept_mumble() call?
rick jones
--
denial, anger, bargaining, depression, acceptance, rebirth...
where do you want to be today?
these opinions are mine, all mine; HP might not want them anyway...
feel free to post, OR email to rick.jones2 in hp.com but NOT BOTH...
On 2007-05-29, Rick Joneswrote:
> Henrik Goldmanwrote:
>> > Have you tried a system call trace to see exactly what is being
>> > passed to accept() for the IPv6 socket? Any chance the previous
>> > accept() call against the IPv4 endpoint has set the values to
>> > something not well liked for an IPv6 socket?
>
>> Are there any tools to do that with?
>
> Well, if you were running Linux I would say use strace. If you were
> running HP-UX I would say use tusc. As for AIX, I would think there
> is a system call trace tool, but I'm not familiar with it. I may have
> run one once or twice while porting netperf, but cannot remember the
> name at the moment.
Um, how about truss? ;-) If found the '-u' flag especially
handy.
> If all else fails, you could use stone knives and bearskins - add a
> printf (sorry I speak C not C++before/after each accept() call to
> display the values of those parameters
Or run your IPv4 and IPv6 code seperately in gdb. I think
http://www-03.ibm.com/servers/aix/pr.../download.html
has a gdb package though it might be a bit out of date ;-)
Regards,
Frank
On 2007-05-27, Henrik Goldmanwrote:
> Once we hit accept() we end up with a errno 22 on the ipv6 socket. From what
> I could see this refers to invalid parameter.
>
> struct sockaddr_storage ClientAddr;
> SOCKET_LEN nAddrLen = sizeof(ClientAddr);
> SOCKET RemoteClientSocket;
>
> // First we try IPv4
> RemoteClientSocket = accept(m_ListenSocket4.GetSocket(), (struct sockaddr *)
> &ClientAddr, &nAddrLen);
>
> // Then we try IPv6
> if (RemoteClientSocket == INVALID_SOCKET)
> {
> if (m_ListenSocket6.GetSocket() != INVALID_SOCKET)
> RemoteClientSocket = accept(m_ListenSocket6.GetSocket(), (struct sockaddr *)
> &ClientAddr, &nAddrLen);
> }
Dunno if you figured this out already. I played around with
some IPv6 socket code (single stacked though) on my 5.3ML4
machine. Works fine for me ;-) In the above, how did you de-
fine the m_ListenSocket6.GetSocket() function? For me a:
int sd = socket(PF_INET6, SOCK_STREAM, 0);
worked. Another potential difference could be your ClientAddr
type. I used the sockaddr_in6 struct from /usr/include/netinet/in.h
No real clue about IPv6 coding, just got interested ;-)
Regards,
Frank
> Dunno if you figured this out already. I played around with
> some IPv6 socket code (single stacked though) on my 5.3ML4
> machine. Works fine for me ;-)
No sorry I have not yet found time to dig further into this.
I'm surprised though. You did not get a errno 22?
I think a bit of work might be needed though.
I see from http://gsyc.es/~eva/IPv6-web/example...Server_v6.html
That it might only be necessary to do 1 accept call.
> In the above, how did you de-
> fine the m_ListenSocket6.GetSocket() function? For me a:
>
> int sd = socket(PF_INET6, SOCK_STREAM, 0);
>
> worked. Another potential difference could be your ClientAddr
> type. I used the sockaddr_in6 struct from /usr/include/netinet/in.h
>
The sockaddr_in6 can make a difference. I know it makes a difference on
other systems because of the size of the structure compared with
sock_storage.
Thanks... I think I got enough input to try to debug this further.
-- Henrik