commit 6b4bf560b6e9d765d44fec4d521ae58071dac77d
parent 16ee54ac8a6630a778aa1d1354c4303a70ca56eb
Author: cnlohr <lohr85@gmail.com>
Date: Sat, 15 Apr 2023 04:42:29 -0400
Fix searchnet. Closes #102
Diffstat:
4 files changed, 121 insertions(+), 8 deletions(-)
diff --git a/Makefile b/Makefile
@@ -48,7 +48,7 @@ cnping_ogl : cnping.c ping.c httping.c resolve.c
cnping_mac : cnping.c ping.c httping.c resolve.c
$(CC) -o cnping $^ -x objective-c -framework Cocoa -framework QuartzCore -lm -lpthread -DOSX
-searchnet : ping.o searchnet.o
+searchnet : ping.c searchnet.c resolve.c
$(CC) $(CFLAGS) -o $@ $^ -lpthread
linuxinstall : cnping
diff --git a/ping.c b/ping.c
@@ -22,6 +22,7 @@ float pingperiodseconds;
int precise_ping;
struct sockaddr_in6 psaddr;
socklen_t psaddr_len;
+int using_regular_ping;
#ifdef WIN_USE_NO_ADMIN_PING
@@ -54,7 +55,10 @@ void ping_setup(const char * strhost, const char * device)
{
// resolve host
psaddr_len = sizeof(psaddr);
- resolveName((struct sockaddr*) &psaddr, &psaddr_len, strhost, AF_INET); // only resolve ipv4 on windows
+ if( strhost )
+ resolveName((struct sockaddr*) &psaddr, &psaddr_len, strhost, AF_INET); // only resolve ipv4 on windows
+ else
+ psaddr.sin6_family = AF_INET;
s_disp = OGCreateSema();
s_ping = OGCreateSema();
@@ -123,12 +127,51 @@ static void * pingerthread( void * v )
return 0;
}
+void singleping(struct sockaddr *addr, socklen_t addr_len )
+{
+ int i;
+ (void) addr;
+ (void) addr_len;
+
+ if( psaddr.sin6_family != AF_INET )
+ {
+ // ipv6 ICMP Ping is not supported on windows
+ ERRM( "ERROR: ipv6 ICMP Ping is not supported on windows\n" );
+ exit( -1 );
+ }
+
+ static int did_init_threads = 0;
+ if( !did_init_threads )
+ {
+ did_init_threads = 1;
+ //Launch pinger threads
+ for( i = 0; i < PINGTHREADS; i++ )
+ {
+ HANDLE ih = pinghandles[i] = IcmpCreateFile();
+ if( ih == INVALID_HANDLE_VALUE )
+ {
+ ERRM( "Cannot create ICMP thread %d\n", i );
+ exit( 0 );
+ }
+
+ OGCreateThread( pingerthread, &pinghandles[i] );
+ }
+ }
+ //This function is executed as a thread after setup.
+
+ if( i >= PINGTHREADS-1 ) i = 0;
+ else i++;
+ OGUnlockSema( s_ping );
+}
+
void ping(struct sockaddr *addr, socklen_t addr_len )
{
int i;
(void) addr;
(void) addr_len;
+ using_regular_ping = 1;
+
if( psaddr.sin6_family != AF_INET )
{
// ipv6 ICMP Ping is not supported on windows
@@ -335,7 +378,7 @@ void listener()
if( !isICMPResponse(buf, bytes) ) continue;
// compare the sender
- if( memcmp(&addr, &psaddr, addrlenval) != 0 ) continue;
+ if( using_regular_ping && memcmp(&addr, &psaddr, addrlenval) != 0 ) continue;
// sizeof(packet.hdr) + 20
int offset = 0;
@@ -366,10 +409,64 @@ void listener()
exit( 0 );
}
+void singleping(struct sockaddr *addr, socklen_t addr_len )
+{
+ int cnt=1;
+
+#ifdef WIN32
+ {
+ //Setup windows socket for nonblocking io.
+ unsigned long iMode = 1;
+ ioctlsocket(sd, FIONBIO, &iMode);
+ }
+#else
+ if ( fcntl(sd, F_SETFL, O_NONBLOCK) != 0 )
+ ERRM("Warning: Request nonblocking I/O failed.");
+#endif
+
+ double stime = OGGetAbsoluteTime();
+
+ struct packet pckt;
+
+ {
+ int rsize = load_ping_packet( pckt.msg, sizeof( pckt.msg ) );
+ memset( &pckt.hdr, 0, sizeof( pckt.hdr ) ); //This needs to be here, but I don't know why, since I think the struct is fully populated.
+#ifdef __FreeBSD__
+ pckt.hdr.icmp_code = 0;
+ pckt.hdr.icmp_type = ICMP_ECHO;
+ pckt.hdr.icmp_id = pid;
+ pckt.hdr.icmp_seq = cnt++;
+ pckt.hdr.icmp_cksum = checksum((const unsigned char *)&pckt, sizeof( pckt.hdr ) + rsize );
+#else
+ pckt.hdr.code = 0;
+ pckt.hdr.type = (psaddr.sin6_family == AF_INET) ? ICMP_ECHO : ICMP6_ECHO_REQUEST;
+ pckt.hdr.un.echo.id = pid;
+ pckt.hdr.un.echo.sequence = cnt++;
+ pckt.hdr.checksum = checksum((const unsigned char *)&pckt, sizeof( pckt.hdr ) + rsize );
+#endif
+
+ int sr = sendto(sd, (char*)&pckt, sizeof( pckt.hdr ) + rsize , 0, addr, addr_len);
+
+ if( sr <= 0 )
+ {
+ ping_failed_to_send = 1;
+ if( using_regular_ping )
+ {
+ ERRMB("Ping send failed:\n%s (%d)\n", strerror(errno), errno);
+ }
+ }
+ else
+ {
+ ping_failed_to_send = 0;
+ }
+ }
+}
+
void ping(struct sockaddr *addr, socklen_t addr_len )
{
int cnt=1;
+ using_regular_ping = 1;
#ifdef WIN32
{
//Setup windows socket for nonblocking io.
@@ -407,7 +504,10 @@ void ping(struct sockaddr *addr, socklen_t addr_len )
if( sr <= 0 )
{
ping_failed_to_send = 1;
- ERRMB("Ping send failed:\n%s (%d)\n", strerror(errno), errno);
+ if( using_regular_ping )
+ {
+ ERRMB("Ping send failed:\n%s (%d)\n", strerror(errno), errno);
+ }
}
else
{
@@ -433,7 +533,7 @@ void ping(struct sockaddr *addr, socklen_t addr_len )
}
}
} while( pingperiodseconds >= 0 );
- //close( sd ); //Hacky, we don't close here because SD doesn't come from here, rather from ping_setup. We may want to run this multiple times.
+ //close( sd ); //Hacky, we don't close here because SD doesn't come from here, rather from ping_setup. We may want to run this multiple times.
}
void ping_setup(const char * strhost, const char * device)
@@ -463,7 +563,11 @@ void ping_setup(const char * strhost, const char * device)
#else
// resolve host
psaddr_len = sizeof(psaddr);
- resolveName((struct sockaddr*) &psaddr, &psaddr_len, strhost, AF_UNSPEC);
+
+ if( strhost )
+ resolveName((struct sockaddr*) &psaddr, &psaddr_len, strhost, AF_UNSPEC);
+ else
+ psaddr.sin6_family = AF_INET;
sd = createSocket();
diff --git a/ping.h b/ping.h
@@ -22,6 +22,8 @@ void listener();
void ping(struct sockaddr *addr, socklen_t addr_len );
void do_pinger( );
+void singleping(struct sockaddr *addr, socklen_t addr_len ); // If using this, must call ping_setup( 0, 0); to begin.
+
//If pingperiodseconds = -1, run ping/do_pinger once and exit.
extern float pingperiodseconds;
extern int precise_ping; //if 0, use minimal CPU, but ping send-outs are only approximate, if 1, spinlock until precise time for ping is hit.
diff --git a/searchnet.c b/searchnet.c
@@ -5,11 +5,14 @@
#include <arpa/inet.h>
#include <stdint.h>
#include <stdlib.h>
+#include "resolve.h"
#include "rawdraw/os_generic.h"
uint32_t my_random_key;
uint8_t send_id[4];
+extern float pingperiodseconds;
+
void * PingListen( void * r )
{
listener();
@@ -50,7 +53,7 @@ int main( int argc, char ** argv )
char dispip[32];
float speed;
- ping_setup();
+ ping_setup( 0, 0);
OGCreateThread( PingListen, 0 );
srand( ((int)(OGGetAbsoluteTime()*10000)) );
my_random_key = rand();
@@ -77,7 +80,11 @@ int main( int argc, char ** argv )
send_id[3] = (cur)&0xff;
// printf( "Pinging: %s\n", dispip );
pingperiodseconds = -1;
- do_pinger( dispip );
+
+ struct sockaddr_in6 psaddr;
+ socklen_t psaddr_len = sizeof(psaddr);
+ resolveName((struct sockaddr*) &psaddr, &psaddr_len, dispip, AF_UNSPEC);
+ singleping((struct sockaddr*) &psaddr, psaddr_len );
OGUSleep( (int)(speed * 1000000) );
}