I'm using libwebsockets 2.0 and I'm having a few issues trying to connect to a server using it as a client.
According to the libwebsockets log, this is what happens when my fairly simple client tries to connect to echo.websocket.org:
[2016/09/25 19:22:56:9033] INFO: lws_header_table_attach: wsi 0x7fe32402a680: ah (nil) (tsi 0, count = 0) in
[2016/09/25 19:22:56:9034] INFO: lws_header_table_attach: wsi 0x7fe32402a680: ah 0x7fe3240078f0: count 1 (on exit)
[2016/09/25 19:22:56:9034] CLIENT: lws_client_connect: direct conn
[2016/09/25 19:22:56:9034] CLIENT: lws_client_connect_2
[2016/09/25 19:22:56:9034] CLIENT: lws_client_connect_2: address
[2016/09/25 19:22:56:9044] ERR: getaddrinfo failed
Callback LWS_CALLBACK_CLIENT_CONNECTION_ERROR (1)
Connection error: (25) getaddrinfo (ipv4) failed
According to this log, it appears to say that getaddrinfo failed, but the line above it (which is supposed to output the address which libwebsockets is connecting to) is returning an empty string.
Even weirder, when I run my test code through Valgrind, everything appears to work fine:
[2016/09/25 19:46:17:7566] INFO: lws_header_table_attach: wsi 0x6714970: ah (nil) (tsi 0, count = 0) in
[2016/09/25 19:46:17:7598] INFO: lws_header_table_attach: wsi 0x6714970: ah 0x65b35c0: count 1 (on exit)
[2016/09/25 19:46:17:7665] CLIENT: lws_client_connect: direct conn
[2016/09/25 19:46:17:7670] CLIENT: lws_client_connect_2
[2016/09/25 19:46:17:7680] CLIENT: lws_client_connect_2: address echo.websocket.org
[2016/09/25 19:46:17:9511] DEBUG: insert_wsi_socket_into_fds: 0x6714970: tsi=0, sock=6, pos-in-fds=1
All of the included examples/tests work just fine, so I'm really not sure where my problem is.
The code at fault is here - I'm not sure whether the issue is within my code or whether it's a library issue.
I was pondering over my code today, trying random things to see if it would fix the issue. Turns out a free in my code was causing issues with libwebsockets:
char* address_internal = malloc(strlen(address) + 1);
memcpy(address_internal, address, strlen(address));
/*...*/
free(address_internal);
Removing free(address_internal); allows the code to work correctly outside of Valgrind.
I'm guessing the problem is that lws_parse_uri doesn't create its own internal copy, which the docs don't clearly mention. What's weird is that Valgrind didn't pick up on this, and somehow allowed the memory to still be used.
Related
I am trying to understand basics of RPC using RPCGen. I followed a basic tutorial and wrote the follwing myrpc.x file
program MESSAGEPROG {
version EVALMESSAGEVERS {
int EVALMESSAGE(string) = 1;
} = 1;
} = 0x20000002;
I compile it by running
rpcgen -a -C myrpc.x
In the resulting server.c file, I added a printf statement as below
printf("Message is: %s,\n", *argp);
Then i run make -f Makefile.myrpc and start the server by running myrpc_server. Now when i run the client 'myrpc_client', I get the following message printed in the server
Message is: H���5�
Now my question is from where does this argument come from "H���5�" as this is not the argument which i am when running the client? Also can someone explain me how do i start running complex programs with rpcgen?
The garbage value is from code on line 15 in client.c, where is uninitialized variable used as an argument for your rpc call. My version of rpc show an error:
call failed: RPC: Can't encode arguments"
15 char * evalmessage_1_arg;
"How do I start running complex programs with rpc?" It' just on you. We cannot say when you need to use rpc. You probably have some reason for what you chose this implementation.
Some use case for rpc is thin client on slow computer, which needs some expensive computation. Client sends data to powerful server, that do the hard work and returns result.
I'm having some problems with Libstrophe. I was able to make it work in linux (fedora) but seems that Windows is not going to be so easy.
Running basic.exe I have the following output (server was dukgo.com):
TLSS DEBUG QuerySecurityPackageInfo() success
TLSS DEBUG AcquireCredentialsHandle() success
conn DEBUG SENT: <starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>
xmpp DEBUG RECV: <proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>
xmpp DEBUG handle proceedtls called for proceed
xmpp DEBUG proceeding with TLS
TLSS DEBUG QuerySecurityPackageInfo() success
TLSS DEBUG AcquireCredentialsHandle() success
xmpp DEBUG Couldn't start TLS! error -2146893018
conn DEBUG SENT: </stream:stream>
xmpp DEBUG Socket closed by remote host.
xmpp DEBUG Closing socket.
DEBUG: disconnected
event DEBUG Stopping event loop.
event DEBUG Event loop completed.
The problem seems to be located in src\tls_schannel.c:331
ret = tls->sft->InitializeSecurityContextA(&(tls->hcred), &(tls->hctxt), name,
ctxtreq, 0, 0, &sbdin, 0,
&(tls->hctxt), &sbdout,
&ctxtattr, NULL);
}
if (ret == SEC_E_OK) {
ret value is -2146893018 instead of SEC_E_OK. I see some post about this problem and I changed to OpenSLL but has no use, still not working. Also in those cases DecryptMessage() was mentioned, I never reach that line in of code so far. DecryptMessage returning SEC_E_UNSUPPORTED_FUNCTION
If anyone have an idea about this I would be really thankful, I had trying to fix this for over a week and still nothing.
thanks, federico.
pd.: I have warnings like "warning LNK4006: __NULL_IMPORT_DESCRIPTOR already defined in libeay32MTd.lib(LIBEAY32.dll); second definition ignored" I assume that openssl is working anyways
I want to use mongodb c driver in my project, I'm on Windows 7 so built it with command :
scons --m32 --c99
My problem is I can't make the Connecting example work :
#include <stdio.h>
#define MONGO_HAVE_STDINT
#include "mongo.h"
int main() {
mongo conn[1];
int status = mongo_client( conn, "127.0.0.1", 27017 );
printf("status %d, err %d", status, conn->err);
mongo_destroy( conn );
return 0;
}
Whether mongod is running on my machine or not, the output of executing the exe is :
$ ./mongodb_example.exe
status -1, err 3
Error 3 corresponds to MONGO_CONN_ADDR_FAIL error code (An error occured while calling getaddrinfo()).
Any suggestion about how to connect successfully ?
Updates:
version is mongodb-mongo-c-driver-v0.8.1-0-g8f27c0f
So there are two things you need to do to make this work:
When building with scons, you need to make sure you that you enable the "standard-env" target like so:
scons --m32 --standard-env
Secondly in your code and in addition to the MONGO_HAVE_STDINT that you already have, make sure you call mongo_init_sockets() before establishing a connection. This is required on windows.
#include <stdio.h>
#define MONGO_HAVE_STDINT
#include "mongo.h"
int main() {
mongo_init_sockets();
mongo conn[1];
int status = mongo_client( conn, "192.168.2.7", 27017 );
printf("status %d, err %d", status, conn->err);
mongo_destroy( conn );
return 0;
}
So the first part resolves the issue with getaddrinfo() there is an implementation included in the "standard environment". And the second part is a necessary "winsock" initialization that is required on Windows platforms. In the test files this is implemented with a defined macro.
Also make sure you are using a Python 2.7 32bit (not 64bit) as well. Not too sure how valid that is on a current scons release, but it doesn't hurt to be sure.
Some of this is in the documentation you may have missed here, as is the fairly apt description of the mongo_init_sockets() function in the API documentation. Of course, looking at the test files in the distribution did not hurt.
And a little pain for me, as I don't normally build C programs on Windows.
You can get the exact reason of the mongo failure if you print
conn->errcode
conn->errstr
The errcode is the equivalent of errno in linux or GetLastError in Windows.
The errstr will contain the same as a string. So you shall see something like getaddrinfo failed with error <the return status of getaddrinfo>
There could be multiple reasons why getaddrinfo might fail in your system. You can get these values from the man page man gai_strerror (errstr should report this)
EAI_AGAIN temporary failure in name resolution
EAI_BADFLAGS invalid value for ai_flags
EAI_BADHINTS invalid value for hints
EAI_FAIL non-recoverable failure in name resolution
EAI_FAMILY ai_family not supported
EAI_MEMORY memory allocation failure
EAI_NONAME hostname or servname not provided, or not known
EAI_OVERFLOW argument buffer overflow
EAI_PROTOCOL resolved protocol is unknown
EAI_SERVICE servname not supported for ai_socktype
EAI_SOCKTYPE ai_socktype not supported
EAI_SYSTEM system error returned in errno
I haven't used the mongodb c driver, so this is just a guess. From the tutorial, it looks like you skipped the initialization step:
http://api.mongodb.org/c/current/tutorial.html
mongo conn[1];
mongo_init( conn );
...
mongo_client( conn, "127.0.0.1", 27017 );
I'm using C language to send data via socket in Linux by using command
send(ServerSocket, cSendBuff, strlen(cSendBuff), 0);
The procedure is:
Create socket
Connect to Server
while (condition): Send data
When I run this program in Linux environment, if it is connected, there is no problem. But in order to take care of failed connection when running, I check some cases and got results as below:
Case 1:
Create socket: No creation (comment out creating function)
Connection to Server: No connection (comment out connecting function)
Send data --> Failed (return -1) but no crash
Case 2:
Create socket: Successfully
Connection to Server: Failed or even No connection (comment out
connecting function)
Send data --> Crash
And then, i tried 3 different values of socket WITHOUT connection to server
Case 3:
ServerSocket = -1 --> Send data: Failed
ServerSocket = 0 --> Send data: Failed
ServerSocket = 4 --> Send data: Crash
In case of failed sending, it is correct but I don't understand why i got crash in other cases. I tried with Windows but no problem, is that a different between Linux and Windows? does it make sense? I want to open socket and connect to server only once time and after that sending data a thousand times, so if "the crash" makes sense in this case, how can I fix this problem in case of failed connection? Thanks for your time.
Here is the Case 2 (connect failed by stopping Server in order to test a case of failed connection):
ServerSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_IP) ;
...
iResult = connect(ServerSocket,(struct sockaddrx *)&server , sizeof(server));
iResult = send(ServerSocket, cSendBuff, strlen(cSendBuff), 0);
if(iResult<0)
{...}
Here is the Case 3:
//ServerSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_IP) ;
...
//iResult = connect(ServerSocket,(struct sockaddrx *)&server , sizeof(server));
ServerSocket = 0;
iResult = send(ServerSocket, cSendBuff, strlen(cSendBuff), 0);
log();
ServerSocket = -1;
iResult = send(ServerSocket, cSendBuff, strlen(cSendBuff), 0);
log();
ServerSocket = 4;
iResult = send(ServerSocket, cSendBuff, strlen(cSendBuff), 0);
log();
if(iResult<0)
{...}
Your program does not crash!
It receives a SIGPIPE signal because the local end of the socket has been shut down. Read man 2 send, especially the EPIPE error case. (So, to be precise, your program is terminated due to an unhandled SIGPIPE signal.)
As the man 7 signal man page says, the default disposition for SIGPIPE is to terminate the process. To avoid the termination, either set a SIGPIPE signal handler, or use send(socket, buffer, length, MSG_NOSIGNAL).
Do not use Windows as your measuring stick. It is not a sane method. You have much better, actually reliable documentation available. The Linux man-pages project is one of the best sources for the C library documentation (section 3). Even though it is focused on Linux and GNU C library, every page has a Conforming to section which tells you when and where that functionality is available.
The above links refer to the up-to-date web pages, but you can also use man 2 send, man 7 signal on the command line to browse the same information. The web pages are more up to date than the distributions, but the project only includes standard man pages, not those installed by applications or extra libraries you might have.
Questions?
Case 2.3: This should fail, by which I mean it should return -1 with an accompanying value of errno. You don't state what you mean by 'fail' or 'crash,' so it is impossible to comment further.
Case 3:
These should all fail ditto unless FD 0 or 4 happens to be a socket.
I have no idea why you're even testing any of this. A 'failed connection' is a completely different thing from a socket that has never been connected in the first place. A 'failed connection' manifests itself as a -1 return from send(), recv(), and friends, with an accompanying value of errno other than EAGAIN/EWOULDBLOCK. You can't send to a TCP socket that isn't connected, and it shouldn't be possible for your code to even attempt it. If it is, your error handling code path is incorrect.
I thought I would try out SDP on our infiniband hardware.
However, when I try to add AF_INET_SDP as the first argument to socket() I get the following error:
"Address family not supported by protocol".
Originally I had:
#define AF_INET_SDP 26
But after doing some reading, noticed a patch applied some time back to change this value to 27.
When set to 26 I get the error:
"Error binding socket: No such device"
Has anyone managed to get SDP working on Ubuntu 12.04? what did you do to get it up and running?
I have installed libsdp1 and libsdpa-dev
Using the LD_PRELOAD method on iperf I also get the first error:
LD_PRELOAD=libsdp.so iperf -s
dir: /tmp/libsdp.log.1000 file: /tmp/libsdp.log.1000/log
socket failed: Address family not supported by protocol
bind failed: Bad file descriptor
Therefore I assume 27 is the correct domain number.
SDP hasn't been accepted on the mainline linux kernel. On recent fedora, they don't ship it, neither the user space libsdp.
If you still want to experiment, Matt is right, the module in question is 'ib_sdp'.
try modprobe ib_sdp and run your example again.