JNI/C socket connection error on Solaris 11

主宰稳场 提交于 2021-02-10 18:00:24

问题


Our application uses several socket connections (to localhost) implemented in c, with one connection using a jni/c socket connection. All of them call the same include to open the socket, and all are successful when we run the application on Solaris 10. Migrating to Solaris 11, we are finding that only the socket connections built in c are working, the one jni/c connection will not. I've added output to see what exactly is being sent to the connect call and it looks like the call is getting everything it needs:

"sock_connect: socket status: 0, sock_d: 27, serv_addr: ***.***.***.***, sizeof: 16"

So for the call below, sock_d = 27
                       serv_addr = (it returns a good IP, but my PM said he'd kill me if I put the actual IP) 
                       sizeof(serv_addr) = 16
which should be all the parameters connect() needs in the code snippet below.

.
.
.
.
status = connect(sock_d, (struct sockaddr *)&serv_addr, sizeof(serv_addr));

if (status < 0){
   fprintf(stderr, "sock_connect 4: after connect errno: %i, error %sn", errno, strerror(errno));
   if (errno == EINPROGRESS){
      fprintf(stderr, "sock_connect, errno == EINPROGRESS\n");
.
.
.

Truss output for the failed connection seems to indicate an EINPROGRESS error. Our code is supposed to validate for this possibility, but it does not trigger an if statement that checks to see if the error == EINPROGRESS. It never reaches the second fprintf statement. We have disabled IPv6 on the server, as we thought perhaps java was trying to force this protocol, but this didn't make a difference either.

The exact same libraries and executables will work on both servers, right up until the jni socket call is made. From that point on Solaris 10 keeps going but Solaris 11 will not.

Has anyone seen this before? Please let me know what else you need to see and I'll post it. Thanks in advance!


回答1:


This code incorrectly assumes fprintf() will never modify errno:

if (status < 0){
   fprintf(stderr, "sock_connect 4: after connect errno: %i, error %sn", errno, strerror(errno));
   if (errno == EINPROGRESS){
      fprintf(stderr, "sock_connect, errno == EINPROGRESS\n");

The POSIX standard for errno states (emphasis mine):

The value of errno shall be defined only after a call to a function for which it is explicitly stated to be set and until it is changed by the next function call or if the application assigns it a value.

And per the Solaris 11.3 fprintf() man page, fprintf() can set errno:

Errors

For the conditions under which printf(), fprintf(), and dprintf() will fail and may fail, refer to fputc(3C) or fputwc(3C).

The snprintf() function will fail if:

EOVERFLOW

The value of n is greater than INT_MAX or the number of bytes needed to hold the output excluding the terminating null is greater than INT_MAX.

All forms of printf() will fail if:

EILSEQ

A wide-character code that does not correspond to a valid character has been detected.

EINVAL

There are insufficient arguments.

The dprintf() function will fail if:

EBADF

The fildes argument is not a valid file descriptor.

The printf(), fprintf(), dprintf(), and asprintf() functions may fail due to an underlying malloc(3C) failure if:

EAGAIN

Storage space is temporarily unavailable.

ENOMEM

Insufficient storage space is available.



来源:https://stackoverflow.com/questions/49701612/jni-c-socket-connection-error-on-solaris-11

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!