python's 'connect_ex' equivalent in C++ - c++

I'm trying to check whether an address is available for connection in C++.
In python it's quite simple, I make a socket and call 'connect_ex' like so:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
res = s.connect_ex((other_host,other_port))
if res == 0:
print("connection available")
Is there a C++ equivalent to this?

Python connect_ex is actually C/C++ connect. Both Python connect and connect_ex do essentially the same, i.e. connecting to the given peer. The only difference is that connect throws an exception if the connection fails while connect_ex simply returns an error.
From the documentation:
Like connect(address), but return an error indicator instead of raising an exception for errors returned by the C-level connect() call (other problems, such as “host not found,” can still raise exceptions). The error indicator is 0 if the operation succeeded, otherwise the value of the errno variable. This is useful to support, for example, asynchronous connects.
Since C/C++ don't raise an exception on connect, they are more like connect_ex in the first place. There is no need to have an extra function for what the original function is already doing.
Looking at the source code you will see that both connect and connect_ex essentially call internal_connect, either with raise=1 or raise=0. And internal_connect is doing C connect.

Related

Setting useUnsafeHeaderParsing for C++ WinHttp

I'm trying to reach a web page on an embedded device.
I'm using WinHttp on Win32.
When trying to read response I get error
ERROR_WINHTTP_INVALID_SERVER_RESPONSE
12152
The server response cannot be parsed.
But when I captured with WireShark I can see that response is coming.
So to test I wrote a simple C# program.
GetResponse was throwing exception
The server committed a protocol violation. Section=ResponseHeader
Detail=CR must be followed by LF
So according to below solution I set useUnsafeHeaderParsing to true. And it worked fine.
HttpWebRequestError: The server committed a protocol violation. Section=ResponseHeader Detail=CR must be followed by LF
Since I can't use C# I need to find a way to set useUnsafeHeaderParsing to true for WinHttp with win32 C++
Many thanks
I've briefly looked into the option flags of WinHttpSetOption and found the following entry:
WINHTTP_OPTION_UNSAFE_HEADER_BLOCKING
This option is reserved for internal use and should not be called.
Since the option looks linke an on/off switch I would try to do the following:
BOOL bResult;
BOOL bOption = FALSE;
bResult = WinHttpSetOption(hInternet,
WINHTTP_OPTION_UNSAFE_HEADER_BLOCKING,
&bOption,
sizeof(bOption));
if (bResult == FALSE)
{
/* handle error with GetLastError() */
}
Well but as MSDN says it's reserved for internal use and therefore the function may change in the future (or has already changed in the past). But it's worth a try... Good Luck!
Looks like the name of the option must have changed since then: with the current SDK it's WINHTTP_OPTION_UNSAFE_HEADER_PARSING. Also, I verified (by examining the Assembly code directly) that:
the option must be DWORD-sized
the value of the option doesn't matter, as long as it's nonzero
you can only enable unsafe parsing; trying to disable (by setting the option value to zero) causes an error to be returned
Obviously, since this undocumented, it's subject to change.

ora-24399- Invalid number of connections specified -OCCI program

I am using following simple code to connect to database and I am getting error as ORA-24399 which says invalid number of connections specified. I have googled enough but not clue. This is a CPP program.
Following is code Snippet:
try
{
Environment *env = Environment::createEnvironment(Environment::DEFAULT);
Connection *con= env->createConnection("test","test","testdb");
}
catch(SQLException ex)
{
cout<<ex.getMessage().c_str();
}
P.S Using SQL Plus I am able to connect to the database where this code is being run. There are no issues there. Only through program there is a failure seen.
P.P.S Tried using connectionpool as well but still no luck...
Looking at your error, it seems that the problem is somewhere else in your code: you should fix the parameters (related to connection numbers) in the call to OCIConnectionPoolCreate.

Is it possible to force OpenSSL to not generate SIGPIPE without global signal handler change?

I write static library that that refers to static OpenSSL library. OpenSSL generates SIGPIPE sometimes and crashes program. I know that it is possible to use signal function to disable SIGPIPE globally. However, for static library such requirement is not elegant (unlike shared library where you can call signal in initialization function). Also the method that doesn't need global changes in program is much better, because who knows may be any other library requires SIGPIPE and will conflict with library that requires to ignore this signal. I think good practice is to change BIO only and nothing else.
OpenSSL uses sockets, and sockets send function contains good solution (MSG_NOSIGNAL flag). Is there any similar solution for OpenSSL? Is there any way to setup OpenSSL BIO in such a way that it will not generate SIGPIPE and not crash entire program?
OpenSSL does not generate SIGPIPE by itself. But, OpenSSL uses sockets and if you write to a socket where the other end is closed already a SIGPIPE will be generated. If you don't want this you have to handle SIGPIPE (like setting it to SIG_IGN). This will then cause the write to return EPIPE error.
Because this behavior is not specific to OpenSSL but common to all sockets and because this is a global setting you should not change it in your library. You might mention it in the documentation, but this should be only necessary if you expect a user which is not familiar with the standard behavior of sockets.
OpenSSL generates SIGPIPE sometimes and crashes program
I don't believe its OpenSSL; rather, its the operating system in response to the peer closing the SSL socket in a "dirty" manner.
Eric Rescorla touches upon it An Introduction to OpenSSL Programming (Part I):
When we send our close_notify, the other side may send a TCP RST
segment, in which case the program will catch a SIGPIPE. We install
a dummy SIGPIPE handler in initialize_ctx() to protect against
this problem.
I don't agree with "do nothing but document it". If RTFM was going to work, then it would have happened by now. Its not OK to crash the application and claim the answer is in the manual somewhere. You should do the right thing out of the box and document how to change the behavior.
Perhaps you should install the SIGPIPE handler if the program does not install one itself. If the program installs one, then you maybe should provide a code path back into your library to notify you when it occurs (if you need it).
You can test for an existing SIGPIPE handler (and install one if not present) with something like the following. I use similar in Debug builds to install a SIGTRAP handler so my asserts don't crash the program I am debugging. (Complete coverage with asserts creates self debugging code. I rarely spend any time under a debugger because the code tells me where the problems are).
struct SigPipeHandler
{
SigPipeHandler()
{
// http://pubs.opengroup.org/onlinepubs/007908799/xsh/sigaction.html
struct sigaction old_handler, new_handler={ };
do
{
int ret = 0;
ret = sigaction (SIGPIPE, NULL, &old_handler);
if (ret != 0) break; // Failed
// Don't step on another's handler
if (old_handler.sa_handler != NULL) break;
// Set up the structure to specify the null action.
new_handler.sa_handler = &SigPipeHandler::NullSigPipeHandler;
new_handler.sa_flags = 0;
ret = sigemptyset (&new_handler.sa_mask);
if (ret != 0) break; // Failed
// Install it
ret = sigaction (SIGPIPE, &new_handler, NULL);
if (ret != 0) break; // Failed
} while(0);
}
static void NullSigPipeHandler(int /*unused*/) { }
}
It depends on how you setup SSL over socket. If you are using SSL_set_fd, you can prevent generation of SIG_PIPE with setsocketopt and SO_NOSIGPIPE.

How to capture ping's return value in C++

Does anyone know, how to capture ping's return value in c++? According to this link:
ping should return 0 on success, 1 on failure such as unknown host, illegal packet size, etc. and 2 On a unreachable host or network.
In C++ I called ping with the system (), e.g. int ret = system("ping 192.168.1.5");.
My problem is, that ret's value is 0 or 1. It will never 2! If I think correctly, this is because, this return value I get, is the system functions return value, not ping's. So how could i get ping's return vlaue?
Thanks in advance!
kampi
Edit:
Right now i use this system("ping 192.169.1.5 > ping_res.txt"); but i don't want to work with files (open, and read them), that's why i want to capture, th return value , if possible :)
If you are on Windows, it might be better to use IcmpSendEcho2 directly to implement the ping functionality in your application.
A simple solution would be pipe the output of ping to to a file and read it.
E.g.
system("ping 192.169.1.5 > ping_res.txt");
And read ping_res.txt to get the info you need.
From man 3 system on Linux:
RETURN VALUE
The value returned is -1 on error (e.g. fork(2) failed), and the return status of the command otherwise. This latter return status is in the format specified in wait(2).
Then from man 2 wait on Linux:
If status is not NULL, wait() and waitpid() store status information in the int to which it points. This integer can be inspected with the following macros (which take the integer itself as an argument, not a pointer to it, as is done in wait() and wait- pid()!):
WIFEXITED(status)
returns true if the child terminated normally, that is, by calling exit(3) or _exit(2), or by returning from main().
WEXITSTATUS(status)
returns the exit status of the child. This consists of the least significant 8 bits of the status argument that the child specified in a call to exit(3) or _exit(2) or as the argument for a return statement in main(). This macro should only be employed if WIFEXITED returned true.
From sys/wait.h on Linux:
# define WEXITSTATUS(status) __WEXITSTATUS(__WAIT_INT(status))
From bits/waitstatus.h on Linux:
/* If WIFEXITED(STATUS), the low-order 8 bits of the status. */
#define __WEXITSTATUS(status) (((status) & 0xff00) >> 8)
In other words, you will wan to use these macros if you are using Linux. Are you using HP-UX? I notice you link to information for HP-UX. If so, what does your man 3 system page say?
Also, keep in mind that system invokes "sh -c command" and you will receive the return value of sh:
EXIT STATUS
The following exit values shall be returned:
0 The script to be executed consisted solely of zero or more blank lines or comments, or both.
1-125 A non-interactive shell detected a syntax, redirection, or variable assignment error.
127 A specified command_file could not be found by a non-interactive shell.
Otherwise, the shell shall return the exit status of the last command it invoked or attempted to invoke (see also the exit utility in Special Built-In Utilities).
What return value do you find if you attempt, e.g., system("exit 203");?
So you just want to know the return value: i.e. "0 on success, 1 on failure such as unknown host, illegal packet size, etc. and 2 On a unreachable host or network." I think using ping is an overkill in this case. Writing to file and reading from it is apparently a little bit ugly.
I think you should just try **open()**ing a connection to the host on port 7 (Echo). Then you would get the information that ping return value would tell you. If you further want to get response durations, you can measure it yourself by sending arbitrary data to the host on echo port. It would take some time to write the code but i think it's worth for flexibility and accuracy.

QAbstractSocket::UnknownSocketError

What could be cause of QAbstractSocket::UnknownSocketError when using QTcpSocket?
CODE
I'm getting this error code with the following code:
this->connect(socket, SIGNAL(socketError(QAbstractSocket::SocketError)), SLOT(handleSocketError(QAbstractSocket::SocketError)));
...
void MyClass::handleSocketError(QAbstractSocket::SocketError error)
{
qDebug() << error;
}
MORE INFO
The QTcpSocket is trying to connect to some remote host. And it fails with mentioned error code.
If you read the code, you'll see that this error means exactly what it says: "something bad happened and I don't know why". There had to be exceptions, of course:
The socket is not connected to a server and you try to write to it (src/network/socket/qabstractsocket.cpp on line 2025)
An SSL error occurred (src/network/ssl/qsslsocket_openssl.cpp in a lot of places)
In both situations the errorString is set to an appropriate message.
Possibly you called the error() function when there is no error.
Looking for AbstractSocketError in the Qt sources gives quite some hits. Maybe fire up a debugger and look into the backtrace when you get the error() signal. Possibly an exotic error condition occured in the underlying socket engine (which is a Qt internal class).
Does remote host require ssl connection? It may be problem if your Qt copy can't load libssl. I had same problem (UnkownSocketError) when Qt couldn't find libssl