Cannot connect to https server using mbedtls example client - c

EDIT: I tested with a static IP on both the board and my computer with a python SSL server and it works as expected, leading me to believe that the DHCP is the problem. If anyone has a lead on what may be occuring it would be greatly appreciated.
I am using the mbedTLS library on a STM32F746-NUCLEO board and I want to use it as both a SSL client and server. The server works well, so i tried to use the client example code (as is, in a separate project).
The following mbedtls_net_connect call returns -68 (MBEDTLS_ERR_NET_CONNECT_FAILED). Digging deeper reveals that it is due to a routing error (line 900 in tcp.c from LwIP), because local_ip is set to 0. The board is in DHCP mode on a home router which is connected to the internet. The destination server is up and running and the SERVER_NAME is the IP address in plain text.
mbedtls_entropy_context client_entropy;
static mbedtls_net_context server_fd;
mbedtls_x509_crt cacert;
static uint32_t flags;
static uint8_t vrfy_buf[512];
static const uint8_t* client_pers = "ssl_client";
mbedtls_ssl_config client_config;
mbedtls_ctr_drbg_context client_ctr_drbg;
mbedtls_ssl_context client_ssl;
static uint8_t client_buf[1024];
void SSL_Server(void const *argument) {
int ret, len;
UNUSED(argument);
mbedtls_net_init(&server_fd);
mbedtls_ssl_init(&client_ssl);
mbedtls_ssl_config_init(&client_config);
mbedtls_x509_crt_init(&cacert);
mbedtls_ctr_drbg_init(&client_ctr_drbg);
// Seeding the random number generator
mbedtls_entropy_init( &client_entropy );
len = strlen((char *) client_pers);
if((ret = mbedtls_ctr_drbg_seed(&client_ctr_drbg, mbedtls_entropy_func,
&client_entropy, (const unsigned char *) client_pers, len)) != 0)
{
goto exit;
}
// 1. Initialize certificates
ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_cas_pem,
mbedtls_test_cas_pem_len );
if( ret < 0 )
{
goto exit;
}
if((ret = mbedtls_net_connect(&server_fd, SERVER_NAME, SERVER_PORT,
MBEDTLS_NET_PROTO_TCP)) != 0)
{
mbedtls_printf( " failed\n ! mbedtls_net_connect returned %d\n\n", ret );
goto exit;
}
}
Here the SSL_Server function is a FreeRTOS thread called in the main(). I can also confirm that the network interface has been assigned an IP address when the error occurs.
I expect the connection call to return 0 and connect to the server to initiate the SSL handshake.

You need to set the default netif route for LWIP to be able to route the remote address.
Simply add netif_set_default(&netif); after dhcp_start() inside the function mbedtls_net_init().
void mbedtls_net_init( mbedtls_net_context *ctx ) {
...
/* add the network interface */
netif_add(&netif, &addr, &netmask, &gw, NULL, &ethernetif_init, &ethernet_input);
/* register the default network interface */
netif_set_up(&netif);
#ifdef USE_DHCP
netif.ip_addr.addr = 0;
dhcp_start(&netif);
#endif
netif_set_default(&netif); // <-- Here
osDelay(500);
start = HAL_GetTick();
while((netif.ip_addr.addr == 0) && (HAL_GetTick() - start < 10000))
{
}
if (netif.ip_addr.addr == 0) {
printf(" Failed to get ip address! Please check your network configuration.\n");
Error_Handler();
}
...
The documentation for MbedTLS can be kinda tricky, hope this helps.

Related

Cannot move camera using libuvc

I'm trying to control my camera using libuvc.
I tried this code I modified from the example:
#include <libuvc/libuvc.h>
#include <stdio.h>
#include <unistd.h>
int main() {
uvc_context_t *ctx;
uvc_device_t *dev;
uvc_device_handle_t *devh;
uvc_stream_ctrl_t ctrl;
uvc_error_t res;
/* Initialize a UVC service context. Libuvc will set up its own libusb
* context. Replace NULL with a libusb_context pointer to run libuvc
* from an existing libusb context. */
res = uvc_init(&ctx, NULL);
if (res < 0) {
uvc_perror(res, "uvc_init");
return res;
}
puts("UVC initialized");
/* Locates the first attached UVC device, stores in dev */
res = uvc_find_device(
ctx, &dev,
0, 0, NULL); /* filter devices: vendor_id, product_id, "serial_num" */
if (res < 0) {
uvc_perror(res, "uvc_find_device"); /* no devices found */
} else {
puts("Device found");
/* Try to open the device: requires exclusive access */
res = uvc_open(dev, &devh);
if (res < 0) {
uvc_perror(res, "uvc_open"); /* unable to open device */
} else {
puts("Device opened");
uvc_print_diag(devh, stderr);
//uvc_set_pantilt_abs(devh, 100, 100);
int result = uvc_set_pantilt_abs(devh, 5, 50);
printf("%d\n", result);
//sleep(5);
/* Release our handle on the device */
uvc_close(devh);
puts("Device closed");
}
/* Release the device descriptor */
uvc_unref_device(dev);
}
/* Close the UVC context. This closes and cleans up any existing device handles,
* and it closes the libusb context if one was not provided. */
uvc_exit(ctx);
puts("UVC exited");
return 0;
}
I tried both uvc_set_pantilt_abs and uvc_set_pantilt_rel and both are returning 0 so it means the action is successful. Except the camera does not move.
I'm sure the camera uses UVC because uvc_print_diag indicates
VideoControl:
bcdUVC: 0x0110
Am I doing something wrong? If not how can I troubleshoot it?
I found the answer a while ago but forgot to put it here.
I stumbled upon this project which controls a camera using a commandline tool with libuvc.
After playing a bit with it and compared it with my code I got what I did wrong. He was getting the pantilt data from the camera and then using it to send requests. It seems cameras need to receive a number which must be a multiple of the "step" provided by the camera as the movement unit.
Here's the part where he requests the pantilt information:
int32_t pan;
int32_t panStep;
int32_t panMin;
int32_t panMax;
int32_t tilt;
int32_t tiltStep;
int32_t tiltMin;
int32_t tiltMax;
// get current value
errorCode = uvc_get_pantilt_abs(devh, &pan, &tilt, UVC_GET_CUR);
handleError(errorCode, "Failed to read pan/tilt settings - possibly unsupported by this camera?\n");
// get steps
errorCode = uvc_get_pantilt_abs(devh, &panStep, &tiltStep, UVC_GET_RES);
handleError(errorCode, "Failed to read pan/tilt settings - possibly unsupported by this camera?\n");
// get min
errorCode = uvc_get_pantilt_abs(devh, &panMin, &tiltMin, UVC_GET_MIN);
handleError(errorCode, "Failed to read pan/tilt settings - possibly unsupported by this camera?\n");
// get max
errorCode = uvc_get_pantilt_abs(devh, &panMax, &tiltMax, UVC_GET_MAX);
handleError(errorCode, "Failed to read pan/tilt settings - possibly unsupported by this camera?\n");
Here's the full code

SDLNet Networking Not Working

I am working on a game written in C using SDL. Given that it already uses SDL, SDL_image, and SDL_ttf, I decided to add SDL_mixer and SDL_net to my engine. Getting SDL_mixer set up and working was very easy, but I am having a lot of trouble with SDL_net.
To test I created a very simple application with the following rules:
Run without arguments act as a TCP server on port 9999
Run with an argument try to connect to the server at the given IP address on port 9999
Here are some of the key lines of the program (I'm not going to post my whole event-driven SDL engine because its too long):
char *host = NULL;
if (argc > 1) host = argv[1];
and...
IPaddress ip;
TCPsocket server = NULL;
TCPsocket conn = NULL;
if (host) { /* client mode */
if (SDLNet_ResolveHost(&ip,host,port) < 0)
return NULL; //this is actually inside an engine method
if (!(conn = SDLNet_TCP_Open(&ip)))
return NULL;
} else { /* server mode */
if (SDLNet_ResolveHost(&ip,NULL,port) < 0)
return NULL;
if (!(server = SDLNet_TCP_Open(&ip)))
return NULL;
}
and... inside the event loop
if (server) {
if (!conn)
conn = SDLNet_TCP_Accept(server);
}
if (conn) {
void *buf = malloc(size); //server, conn, size are actually members of a weird struct
while (SDLNet_TCP_Recv(conn,buf,size))
onReceive(buf); //my engine uses a callback system to handle things
free(buf);
}
The program seems to start up just fine. However for some reason when I run it in client mode trying to connect to my home computer (which I have on a different IP) from my laptop I find that the call to SDLNet_TCP_Open blocks the program for awhile (5-10 seconds) then returns NULL. Can anybody see what I did wrong? Should I post more of the code? Let me know.

SSL_CONNECT fails with SSL_ERROR_SYSCALL error

Having strange connection failure with openssl SSLConnect with my SSLCLIENT.
We are trying to establish ssl connection with a server. We notice that SSL_CONNECT is failing with error code "SSL_ERROR_SYSCALL".
For further depth we tried printing strerror(errno) which return "scuccess" "0".
However i am just trying to understand what might be the exact cause for this issue
Added code snippet for SSL init and connect::
request some guidance:
int setupSSL(int server){
int retVal = 0;
int errorStatus = 0;
int retryMaxCount = 6;
static int sslInitContext=0;
if(sslInitContext == 0)
{
if(InitCTX() != 0)
{
return -1;
}
else
{
sslInitContext=1;
}
}
retVal = SSL_set_fd(ssl, server); /* attach the socket descriptor */
if ( retVal != 1 )
{
/* perform the connection */
sprintf(debugBuf,"SYSTEM:SOCKET:Could not set ssl FD: %d %s\n",retVal,strerror(retVal));
debug_log(debugBuf,TRACE_LOG);
CloseSocket(server);
return -1;
}
do
{
retVal = SSL_connect(ssl);
errorStatus = SSL_get_error (ssl, retVal);
switch (errorStatus)
{
case SSL_ERROR_NONE:
retVal = 0;
break;
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
retVal = 1;
break;
default:
sprintf(debugBuf,"SYSTEM:SSL_SOCKET:Could not build SSL session(Other error): %d %s\n",errorStatus,strerror(errno));
debug_log(debugBuf,TRACE_LOG);
CloseSocket(server);
return -1;
}
sprintf(debugBuf,"SYSTEM:SSL_SOCKET:SSL CONNECTION Under PROGRESS: %d with remaining retries %d\n",errorStatus,retryMaxCount);
debug_log(debugBuf,TRACE_LOG);
if (retVal)
{
struct timeval tv;
fd_set sockReadSet;
tv.tv_sec = 2;
tv.tv_usec = 0;
FD_ZERO(&sockReadSet);
FD_CLR(server, &sockReadSet);
FD_SET(server,&sockReadSet);
retVal = select(server+1, &sockReadSet, NULL, NULL, &tv);
if (retVal >= 1)
{
retVal = 1;
}
else
{
retVal = -1;
}
retryMaxCount--;
if (retryMaxCount <= 0 )
break;
}
}while(!SSL_is_init_finished (ssl) && retVal == 1);
cert = SSL_get_peer_certificate(ssl);
if(cert == NULL)
{
debug_log("SYSTEM:SSL_SOCKET:Unable to retrive server certificate\n",TRACE_LOG);
CloseSocket(server);
return -1;
}
if(SSL_get_verify_result(ssl)!=X509_V_OK)
{
debug_log("SYSTEM:SSL_SOCKET:Certificate doesn't verify\n",TRACE_LOG);
CloseSocket(server);
return -1;
}
/*X509_NAME_get_text_by_NID (X509_get_subject_name (cert), NID_commonName, peer_CN, 256);
if(strcasecmp(peer_CN, cnName)){
debug_log("SYSTEM:SSL_SOCKET:Common name doesn't match host name\n",TRACE_LOG);
return -1;
}*/
return 0;
// LoadCertificates(ctx, CertFile, KeyFile);
}
int InitCTX(void)
{
int errorStatus = 0;
static int isSslInit = 1;
if(isSslInit)
{
OpenSSL_add_all_algorithms();/* Load cryptos, et.al. */
SSL_load_error_strings();/* Bring in and register error messages */
if(SSL_library_init() < 0)
{
debug_log("SYSTEM:SSL_SOCKET:Could not initialize the OpenSSL library\n",TRACE_LOG);
return -1;
}
method = TLSv1_client_method();
isSslInit=0;
}
ctx = SSL_CTX_new(method);/* Create new context */
if ( ctx == NULL)
{
debug_log("SYSTEM:SSL_SOCKET:Unable to create a new SSL context structure\n",TRACE_LOG);
//sprintf(debugBuf,"SYSTEM:SSL_SOCKET:Unable to create a new SSL context structure: %d %s\n",errorStatus,strerror(retVal));
//debug_log(debugBuf,TRACE_LOG);
return -1;
}
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
if (SSL_CTX_use_certificate_file(ctx,CertFile, SSL_FILETYPE_PEM) <= 0)
{
SSL_CTX_free(ctx);
ctx = NULL;
debug_log("SYSTEM:SSL_SOCKET:Error setting the certificate file.\n",TRACE_LOG);
return -1;
}
/* Set the list of trusted CAs based on the file and/or directory provided*/
if(SSL_CTX_load_verify_locations(ctx,CertFile,NULL)<1)
{
SSL_CTX_free(ctx);
ctx = NULL;
debug_log("SYSTEM:SSL_SOCKET:Error setting verify location.\n",TRACE_LOG);
return -1;
}
SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL);
SSL_CTX_set_timeout (ctx, 300);
ssl = SSL_new(ctx); /* create new SSL connection state */
if(ssl == NULL)
{
sprintf(debugBuf,"SYSTEM:SOCKET:SSL:Unable to create SSL_new context\n");
debug_log(debugBuf,DEBUG_LOG);
if(ctx != NULL)
SSL_CTX_free(ctx);
return -1;
}
return 0;
}
Also is it advised to maintain SSL context for new connections or should we destroy and re init the ssl context??
Added PCAP info:
https://drive.google.com/file/d/0B60pejPe6yiSUk1MMmI1cERMaFU/view?usp=sharing
client: 198.168.51.10 (198.168.51.10), Server: 192.168.96.7 (192.168.96.7)
We are trying to establish ssl connection with a server. We notice that SSL_CONNECT is failing with error code "SSL_ERROR_SYSCALL".
This is usually the case if the other side is simply closing the connection. Microsoft SChannel does this on many kind of handshake problems instead of sending a TLS alert back. This can happen for problems like invalid protocol or no common ciphers etc. It also can happen if you try to do a TLS handshake with a server which does not speak TLS at all on this port. Look at logs at the server side for problems.
Of course it can also be something different so you might check the errno to get more details about the problem. It might also help if you do a packet capture to check what's going on on the wire. Best would be to do this capture on the client and server side to make sure that no middlebox like a firewall is tampering with the connection.
Also is it advised to maintain SSL context for new connections or should we destroy and re init the ssl context??
The context is just a collection of settings, certificates etc and is not affected by the SSL connection itself. You can reuse it for other connection later or at the same time.
EDIT, after the packet capture was attached:
There are multiple TCP connection in the file between client and server and only inside a single one the client tries to initiate a handshake, i.e. the ClientHello can be seen. The server closes the connection. A few things a interesting:
TCP handshake takes very long. The server only replies after 1.6 seconds after receiving the SYN with the SYN+ACK. Also the other replies take 800ms which is very long given that both addresses are in a private network (192.168.0.0). This might indicate a slow connection or VPN (this is about the latency of a satellite link), some middlebox (firewall) slowing everything down or a really slow server.
Client sends TLS 1.0 request. It might be that the server will do only TLS 1.1+. Some TLS stacks (see above) simply close the connection on such errors instead of sending an unsupported protocol alert. But given that the server is slow it might also be old and only support SSL 3.0 or lower.
Client does not use SNI extension. More and more servers need this and might simply close if they don't get the extension.
It is hard to know what really is going on without having access to the server. I recommend to look for error messages on the server side and use tools like SSLyze to check the requirements of the server, i.e. supported TLS versions, ciphers etc.
Apart from that client offers dangerously weak ciphers like various EXPORT ciphers. This looks for me like the defaults of a considerably old OpenSSL version.

noPoll Web socket library in C language always failing to connect

I'am trying to build a open source Cometd Library for C developers, to be able to run a client under barely any given device.
I manage to complete the handshake and data transfer with the longPolling technique, the next step is logically to give the option to the user to choose a Websocket connection.
To ease up the work I decided to use a library for that, I again fetched the internet and found two really relevant libraries:
The WSlay library, which seems to work well but doesn't run under OSX due to the epoll.h include which is not supported by apple.
The NoPoll library, which I think is the best one to use.
The problem is that I can't make it perform right, I always get a failed connections. After reading the full documentation I still don't understand why?
Here is my code:
int main(void)
{
cometd *cometd = cometd_new();
JsonNode *connect = json_node_new(JSON_NODE_OBJECT);
noPollCtx *ctx = nopoll_ctx_new(); //init the context of the lib
noPollMsg *msg; //variable to get messages
if (!ctx) //check if the context is well inited
puts("error ctx is nill");
/*After the new you can enable or disable the Websocket simply do this, enabled by defautl*/
cometd->config->webSockState = true;
cometd_configure(cometd, COMETDOPT_URL, "http://m.zpush.ovh:8080/str/strd");
cometd_configure(cometd, COMETDOPT_MAX_BACKOFF, 5000);
struct _cometd_ext* logger = cometd_ext_logger_new();
cometd_ext_add(&cometd->exts, logger);
cometd_connect(cometd);
connect = cometd_msg_connect_new(cometd);
cometd_transport_send(cometd, connect);
//everything until here is for the handshake wich proceed well and the server returns a successful header
//here i check if the user wants to Websocket upgrade his connection
if (cometd->config->webSockState == true)
{
// here i target the server
noPollConn *conn = nopoll_conn_new(ctx, "54.171.156.38" , "8080" , "m.zpush.ovh:8080" , "ws://m.zpush.ovh:8080/str/strd", NULL, "null");
if (!nopoll_conn_wait_until_connection_ready(conn, 5) )
// here i check if the connection is ready
{puts("nopoll_conn failed"); return (0);}
if (nopoll_conn_send_text (conn, "hello how are you doing, do we connect ?", 40) != 40)
{puts("send text just failed."); return(0);}
else
{
while (nopoll_true) //the loop to receive and send messages
{
msg = nopoll_conn_get_msg(conn);
if (msg)
break;
if (! nopoll_conn_is_ok (conn))
{
puts("connection failed during msg wait");
return nopoll_false;
}
}
}
}
cometd_subscribe(cometd, "/service/GmY-HuzW/6sd0/ls", handler);
cometd_subscribe(cometd, "service/GmY-HuzW/6sd0/updateMeta", handler);
cometd_subscribe(cometd, "/service/GmY-HuzW/6sd0/ls", handler);
cometd_subscribe(cometd, "/service/GmY-HuzW/6sd0/newFile", handler);
cometd_transport_send(cometd, cometd_ping_ls(cometd, "/service/GmY-HuzW/6sd0/ls"));
cometd_listen(cometd);
nopoll_ctx_unref(ctx);
return 0;
}
NoPoll implements a debug option, here is the result :
(proc 49413): (debug) nopoll_ctx.c:260 (nopoll_bool nopoll_ctx_register_conn(noPollCtx *, noPollConn *)) registered connection id 2, role: 0
(proc 49413): (debug) nopoll_conn.c:505 (noPollConn *__nopoll_conn_new_common(noPollCtx *, nopoll_bool, const char *, const char *, const char *, const char *, const char *, const char *)) Created noPoll conn-id=2 (ptr: 0x7f9d00501b60, context: 0x7f9d0041cdf0, socket: 3)
(proc 49413): (debug) nopoll_conn.c:284 (char *__nopoll_conn_get_client_init(noPollConn *)) Created Sec-WebSocket-Key nonce: Z0WLawAAAADGI3syAAAAAA==
(proc 49413): (debug) nopoll_conn.c:551 (noPollConn *__nopoll_conn_new_common(noPollCtx *, nopoll_bool, const char *, const char *, const char *, const char *, const char *, const char *)) Sending websocket client init: GET / HTTP/1.1
Host: 10.0.0.103
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: Z0WLawAAAADGI3syAAAAAA==
Origin: http://10.0.0.103
Sec-WebSocket-Version: 13
(proc 49413): (critical) nopoll_conn.c:643 (noPollConn *__nopoll_conn_new_common(noPollCtx *, nopoll_bool, const char *, const char *, const char *, const char *, const char *, const char *)) ***Failed to send websocket init message, error code was: 57 (2), closing session***
(proc 49413): (debug) nopoll_conn.c:1036 (void nopoll_conn_shutdown(noPollConn *)) shutting down connection id=2 (session: 3, role: client)
(proc 49413): (debug) nopoll_conn.c:651 (noPollConn *__nopoll_conn_new_common(noPollCtx *, nopoll_bool, const char *, const char *, const char *, const char *, const char *, const char *)) Web socket initial client handshake sent
-> for better reading : Failed to send websocket init message, error code was: 57 (2), closing session
I really hope some one already successfully used the library and could give me some hints or guide lines. Any help would be very much appreciated, and will give me the ability to finish this library.
The code is still a little bit messy but if you want a full sight of my code I can upload to GitHub.
--> Update :
I found a nasty trick to overcome this problem, i commented line N•845 nopoll_conn_shutdown(); in nopoll_conn.c method wich i think you have guessed it, belongs to the library. Then make install and no more error 57.
Working on your example, I found out that the remote server is closing the connection by reporting the following error:
INFO: conn=0x1238500, conn-id=2, nopoll_conn_is_ok (0x1238500)=1, nopoll_conn_is_ready (0x1238500)=1...sending content
ERROR: connection failed during msg wait, peer reported status=[1011] and reason=[java.text.ParseException: hello how are you doing, do we connect ?]
That is, you are sending unexpected application format for this WebSocket, which is causing the connection close. However, noPoll's support for close frames with body (which includes a status code and a reason) wasn't supported.
I've updated the library and now it is fully supported. You'll have to get a copy of the library from here (use SVN rev 227 at least).
https://dolphin.aspl.es/svn/publico/nopoll/trunk/
http://www.aspl.es/nopoll/downloads.html
Along with that, here is a working updated example that goes to the point I'm talking about plus the couple of functions that will allow you get status and reason reported by remote peer:
#include <nopoll.h>
int main (void) {
/* init the context of the lib */
noPollCtx * ctx = nopoll_ctx_new();
/* variable to get messages */
noPollMsg * msg;
noPollConn * conn;
/* nopoll_log_enable (ctx, nopoll_true);
nopoll_log_color_enable (ctx, nopoll_true); */
if (!ctx) {
puts("error ctx is nill");
return -1; /* do not continue */
}
/* here i target the server */
conn = nopoll_conn_new (ctx, "54.171.156.38" ,
"8080" ,
"m.zpush.ovh:8080" ,
"ws://m.zpush.ovh:8080/str/strd",
NULL, "null");
if (!nopoll_conn_wait_until_connection_ready (conn, 5) ) {
/* here i check if the connection is ready */
puts ("nopoll_conn failed");
return -1;
} /* end if */
printf ("INFO: conn=%p, conn-id=%d, nopoll_conn_is_ok (%p)=%d, nopoll_conn_is_ready (%p)=%d...sending content\n",
conn, nopoll_conn_get_id (conn), conn,
nopoll_conn_is_ok (conn), conn,
nopoll_conn_is_ready (conn));
if (nopoll_conn_send_text (conn, "hello how are you doing, do we connect ?", 40) != 40) {
puts("send text just failed.");
return - 1;
} /* end if */
while (nopoll_true) {
/* the loop to receive and send messages */
msg = nopoll_conn_get_msg(conn);
if (msg)
break;
if (! nopoll_conn_is_ok (conn)) {
printf ("ERROR: connection failed during msg wait, peer reported status=[%d] and reason=[%s]\n",
nopoll_conn_get_close_status (conn),
nopoll_conn_get_close_reason (conn));
return nopoll_false;
}
}
/* close connection always */
nopoll_conn_close (conn);
/* release context */
nopoll_ctx_unref (ctx);
return 0;
}
Best Regards,

Specifying ipv6 interface using glib/gio

I'm trying to use the Gnome glib/gio C library to create a client program to connect to a server via IPv6. My server box has a link local IPv6 address:
inet6 addr: fe80::2d0:c9ff:feda:99e0/64 Scope:Link
So, I to access it, I have to tell the client software which interface to use (eth0 in this case). So the following works (using port 1500):
nc -6 fe80::2d0:c9ff:feda:99e0%eth0 1500
In glib, using the %eth0 notation violates the URI notation:
(process:31159): GLib-GIO-WARNING **: Invalid URI 'none://[fe80:0:0:0:2d0:c9ff:feda:99e0%eth0]:1500'
I've looked in the code and it clearly expects to see the percent escape notation (i.e. the characters '%25') but I can't seem to get the format correct:
** (process:5741): ERROR **: Invalid URI 'none://[fe80:0:0:0:2d0:c9ff:feda:99e0%25eth0]1500'
So, anyone know how to specify the interface?
EDIT: Here's the code
// gchar test[255] = "fe80:0:0:0:2d0:c9ff:feda:99e0%eth0";
// gchar test[255] = "fe80:0:0:0:2d0:c9ff:feda:99e0\%eth0";
// gchar test[255] = "fe80:0:0:0:2d0:c9ff:feda:99e0\x25eth0";
// gchar test[255] = "fe80:0:0:0:2d0:c9ff:feda:99e0\%%25eth0";
gchar test[255] = "[fe80:0:0:0:2d0:c9ff:feda:99e0\%%eth0]";
connection = g_socket_client_connect_to_uri (client,
test,
1500,
NULL,
&error);
EDIT 2: Complete code (with MichaelHampton's input):
#include <glib.h>
#include <gio/gio.h>
int
main (int argc, char *argv[])
{
/* initialize glib */
g_type_init ();
GError * error = NULL;
/* create a new connection */
GSocketConnection * connection = NULL;
GSocketClient * client = g_socket_client_new();
connection = g_socket_client_connect_to_host (client,
(gchar*)"fe80::5054:ff:fe1f:6b6c\%br0",
1500, /* your port goes here */
NULL,
&error);
/* don't forget to check for errors */
if (error != NULL)
{
g_error (error->message);
}
else
{
g_print ("Connection successful!\n");
}
return 0;
}
Ah, you're calling the wrong function. You should be using g_socket_client_connect_to_host to connect directly to a host and port.
Here is a working example:
connection = g_socket_client_connect_to_host (client,
(gchar*)"fe80::5054:ff:fe1f:6b6c\%br0",
1500, /* your port goes here */
NULL,
&error);
The complete example code, which it looked like you were using, was in the related question: GIO socket-server / -client example

Resources