Преглед изворни кода

Added more ipv6 friendly socket stuff.

woollybah пре 8 година
родитељ
комит
732e8fde79
2 измењених фајлова са 197 додато и 9 уклоњено
  1. 68 1
      stdc.mod/stdc.bmx
  2. 129 8
      stdc.mod/stdc.c

+ 68 - 1
stdc.mod/stdc.bmx

@@ -50,6 +50,11 @@ Type TAddrInfo
 
 	Field infoPtr:Byte Ptr
 	Field owner:Int
+	
+	Method New()
+		infoPtr = bmx_stdc_addrinfo_new()
+		owner = True
+	End Method
 
 	Method New(infoPtr:Byte Ptr, owner:Int)
 		Self.infoPtr = infoPtr
@@ -72,18 +77,34 @@ Type TAddrInfo
 		Return bmx_stdc_addrinfo_flags(infoPtr)
 	End Method
 	
+	Method setFlags(flags:Int)
+		bmx_stdc_addrinfo_setflags(infoPtr, flags)
+	End Method
+	
 	Method family:Int()
 		Return bmx_stdc_addrinfo_family(infoPtr)
 	End Method
 	
+	Method setFamily(family:Int)
+		bmx_stdc_addrinfo_setfamily(infoPtr, family)
+	End Method
+	
 	Method sockType:Int()
 		Return bmx_stdc_addrinfo_socktype(infoPtr)
 	End Method
 	
+	Method setSockType(sockType:Int)
+		bmx_stdc_addrinfo_setsocktype(infoPtr, sockType)
+	End Method
+	
 	Method protocol:Int()
 		Return bmx_stdc_addrinfo_protocol(infoPtr)
 	End Method
 	
+	Method setProtocol(protocol:Int)
+		bmx_stdc_addrinfo_setprotocol(infoPtr, protocol)
+	End Method
+	
 	Method addrLen:Int()
 		Return bmx_stdc_addrinfo_addrlen(infoPtr)
 	End Method
@@ -112,6 +133,30 @@ Type TAddrInfo
 	
 End Type
 
+Type TSockaddrStorage
+
+	Field storagePtr:Byte Ptr
+	
+	Method New()
+		storagePtr = bmx_stdc_sockaddrestorage_new()
+	End Method
+
+	Method family:Int()
+	End Method
+	
+	Method address:String()
+		Return bmx_stdc_sockaddrestorage_address(storagePtr)
+	End Method
+
+	Method Delete()
+		If storagePtr Then
+			free_(storagePtr)
+			storagePtr = Null
+		End If
+	End Method
+	
+End Type
+
 'c lib
 Extern "c"
 
@@ -174,7 +219,7 @@ Function atexit_:Int( fun() )="int atexit(void (*)() ) !"
 Function memset_:Byte Ptr( buf:Byte Ptr,val:Int,size:Size_T )="void * memset( void * , int ,size_t ) !"
 Function memcmp_:Int( lhs:Byte Ptr,rhs:Byte Ptr,size:Size_T )="int memcmp( void * , void * , size_t ) !"
 Function memcpy_:Byte Ptr( dst:Byte Ptr,src:Byte Ptr,size:Size_T )="void * memcpy( void * , void * , size_t ) !"
-Function memmove_( dst:Byte Ptr,src:Byte Ptr,size:Size_T )="void * memmove( void * , void * , size_t ) !"
+Function memmove_:Byte Ptr( dst:Byte Ptr,src:Byte Ptr,size:Size_T )="void * memmove( void * , void * , size_t ) !"
 Function strlen_:Size_T( str:Byte Ptr )="size_t strlen( const char *) !"
 
 'math
@@ -207,6 +252,14 @@ Const SO_USELOOPBACK:Int=$40    'bypass hardware when possible
 Const SO_LINGER:Int=$80         'linger on close if data present 
 Const SO_OOBINLINE:Int=$100     'leave received OOB data in line 
 
+Const AI_PASSIVE:Int =     $001 ' Socket address is intended for 'bind'
+Const AI_CANONNAME:Int =   $002 ' Request for canonical name
+Const AI_NUMERICHOST:Int = $004 ' Don't use name resolution
+Const AI_V4MAPPED:Int =    $008 ' IPv4 mapped addresses are acceptable
+Const AI_ALL:Int =         $010 ' Return IPv4 mapped and IPv6 addresses
+Const AI_ADDRCONFIG:Int =  $020 ' Use configuration of this host to choose returned address type
+Const AI_NUMERICSERV:Int = $400 ' Don't use name resolution
+
 'Additional options.
 
 Const SO_SNDBUF:Int=$1001		'sendbuffersize
@@ -240,6 +293,7 @@ Const NI_NOFQDN:Int = $0004
 Const NI_NUMERICHOST:Int = $0008
 Const NI_NUMERICSERV:Int = $0010
 
+Const SOL_SOCKET:Int = $ffff ' options for socket level
 
 'how params for shutdown_
 
@@ -258,6 +312,7 @@ Function gethostbyaddr_:Byte Ptr( addr:Byte Ptr,addr_len:Int,addr_type:Int )
 
 'Function gethostbyname_:Byte Ptr Ptr( name$,addr_type:Int Var,addr_len:Int Var )
 Function getaddrinfo_:TAddrInfo[](name:String, service:String = "http", family:Int = AF_UNSPEC_)
+Function getaddrinfo_hints:TAddrInfo[](name:String, service:String, hints:Byte Ptr)
 
 Function connect_:Int( socket:Int, addrinfo:Byte Ptr )
 Function listen_:Int( socket:Int,backlog:Int )
@@ -283,6 +338,18 @@ Function bmx_stdc_addrinfo_addr:Byte Ptr(info:Byte Ptr)
 Function bmx_stdc_addrinfo_hostname:String(info:Byte Ptr, flags:Int)
 Function bmx_stdc_addrinfo_canonname:String(info:Byte Ptr)
 Function inet_pton_:Int(family:Int, src:String, dst:Byte Ptr)
+Function bmx_stdc_addrinfo_new:Byte Ptr()
+Function bmx_stdc_addrinfo_setflags(info:Byte Ptr, flags:Int)
+Function bmx_stdc_addrinfo_setfamily(info:Byte Ptr, family:Int)
+Function bmx_stdc_addrinfo_setsocktype(info:Byte Ptr, sockType:Int)
+Function bmx_stdc_addrinfo_setprotocol(info:Byte Ptr, protocol:Int)
+
+Function bmx_stdc_bind_info:Int(socket:Int, info:Byte Ptr)
+Function bmx_stdc_sockaddrestorage_new:Byte Ptr()
+Function bmx_stdc_sockaddrestorage_address:String(handle:Byte Ptr)
+Function bmx_stdc_accept_:Int(socket:Int, storage:Byte Ptr)
+Function bmx_stdc_getsockname:String(socket:Int, port:Int Var)
+Function bmx_stdc_getpeername:String(socket:Int, port:Int Var)
 
 'time
 

+ 129 - 8
stdc.mod/stdc.c

@@ -357,7 +357,6 @@ int bmx_stdc_convertAFFamily(int family) {
 	return family;
 }
 
-
 int bind_( int socket,int addr_type,int port ){
 	int r;
 	
@@ -388,28 +387,27 @@ int bind_( int socket,int addr_type,int port ){
 	
 }
 
+int bmx_stdc_bind_info(int socket, struct addrinfo * info) {
+	return bind(socket, info->ai_addr, info->ai_addrlen);
+}
+
 char *gethostbyaddr_( void *addr,int addr_len,int addr_type ){
 	
 	//struct hostent *e=gethostbyaddr( addr,addr_len,addr_type );
 	//return e ? e->h_name : 0;
 }
 
-BBARRAY getaddrinfo_(BBString *name, BBString *service, int family) {
-	struct addrinfo hints;
+BBARRAY getaddrinfo_hints(BBString *name, BBString *service, struct addrinfo * hints) {
 	struct addrinfo * info;
 	struct addrinfo * ip;
 	
-	memset(&hints, 0, sizeof(struct addrinfo));
-	
 	char * n = bbStringToUTF8String(name);
 	char * s = 0;
 	if (service != &bbEmptyString) {
 		s = bbStringToUTF8String(service);
 	}
 	
-	hints.ai_family = bmx_stdc_convertAFFamily(family);
-	
-	int res = getaddrinfo(n, s, &hints, &info);
+	int res = getaddrinfo(n, s, hints, &info);
 	
 	bbMemFree(s);
 	bbMemFree(n);
@@ -436,7 +434,20 @@ BBARRAY getaddrinfo_(BBString *name, BBString *service, int family) {
 	}
 	
 	return arr; 
+}
+
+BBARRAY getaddrinfo_(BBString *name, BBString *service, int family) {
+	struct addrinfo hints;
+	
+	memset(&hints, 0, sizeof(struct addrinfo));
+	
+	hints.ai_family = bmx_stdc_convertAFFamily(family);
+	
+	return getaddrinfo_hints(name, service, &hints);
+}
 
+struct addrinfo * bmx_stdc_addrinfo_new() {
+	return (struct addrinfo *)calloc(1, sizeof(struct addrinfo));
 }
 
 void freeaddrinfo_(struct addrinfo * info ) {
@@ -455,6 +466,12 @@ int accept_( int socket,const char *addr,unsigned int *addr_len ){
 	return accept( socket,(void*)addr,addr_len );
 }
 
+int bmx_stdc_accept_(int socket, struct sockaddr_storage * storage) {
+	int size = sizeof(struct sockaddr_storage );
+	return accept(socket, (struct sockaddr *)storage, &size);
+}
+
+
 int select_( int n_read,int *r_socks,int n_write,int *w_socks,int n_except,int *e_socks,int millis ){
 
 	int i,n,r;
@@ -609,6 +626,22 @@ BBString * bmx_stdc_addrinfo_canonname(struct addrinfo * info) {
 	return bbStringFromUTF8String(info->ai_canonname);
 }
 
+void bmx_stdc_addrinfo_setflags(struct addrinfo * info, int flags) {
+	info->ai_flags = flags;
+}
+
+void bmx_stdc_addrinfo_setfamily(struct addrinfo * info, int family) {
+	info->ai_family = bmx_stdc_convertAFFamily(family);
+}
+
+void bmx_stdc_addrinfo_setsocktype(struct addrinfo * info, int sockType) {
+	info->ai_socktype = sockType;
+}
+
+void bmx_stdc_addrinfo_setprotocol(struct addrinfo * info, int protocol) {
+	info->ai_protocol = protocol;
+}
+
 int bmx_stdc_convertNIFlags(int flags) {
 	int niFlags = 0;
 	
@@ -651,6 +684,94 @@ int inet_pton_(int family, BBString * src, void * dst) {
 	return res;
 }
 
+struct sockaddr_storage * bmx_stdc_sockaddrestorage_new() {
+	return calloc(1, sizeof(struct sockaddr_storage));
+}
+
+BBString * bmx_stdc_sockaddrestorage_address(struct sockaddr_storage * storage) {
+
+	BBString * address = &bbEmptyString;
+	
+#if _WIN32
+
+	TCHAR add[256];
+	typedef LPTSTR (__stdcall RTLIPV6ADDRESSTOSTRING)(const IN6_ADDR*, PTSTR);
+	typedef LPTSTR (__stdcall RTLIPV4ADDRESSTOSTRING)(const IN_ADDR*, PTSTR);
+	
+	HMODULE ntdll = GetModuleHandle("NTDLL.DLL");
+
+	if (storage->ss_family == AF_INET) {
+		RTLIPV4ADDRESSTOSTRING* RtlIpv4AddressToStringFunc = GetProcAddress(ntdll, "RtlIpv4AddressToStringW");
+
+		RtlIpv4AddressToStringFunc(&((struct sockaddr_in*)storage)->sin_addr, add);
+	} else {
+		RTLIPV6ADDRESSTOSTRING* RtlIpv6AddressToStringFunc = GetProcAddress(ntdll, "RtlIpv6AddressToStringW");
+
+		RtlIpv6AddressToStringFunc(&((struct sockaddr_in6*)storage)->sin6_addr, add);
+	}
+	
+	address = bbStringFromWString(add);
+
+#else
+
+	char add[256];
+
+	if (storage->ss_family == AF_INET) {
+		inet_ntop(storage->ss_family, &((struct sockaddr_in*)storage)->sin_addr, add, sizeof(add));
+	} else {
+		inet_ntop(storage->ss_family, &((struct sockaddr_in6*)storage)->sin6_addr, add, sizeof(add));
+	}
+	
+	address = bbStringFromCString(add);
+
+#endif
+
+	return address;
+}
+
+BBString * bmx_stdc_getsockname(int socket, int * port) {
+	struct sockaddr_storage storage;
+	int len = sizeof(struct sockaddr_storage);
+	
+	BBString * address = &bbEmptyString;
+	*port = 0;
+	
+	int res = getsockname(socket, (struct sockaddr *)&storage, &len);
+	
+	if (res >= 0) {
+		if (storage.ss_family == AF_INET) {
+			*port = ((struct sockaddr_in*)&storage)->sin_port;
+		} else {
+			*port = ((struct sockaddr_in6*)&storage)->sin6_port;
+		}
+		
+		address = bmx_stdc_sockaddrestorage_address(&storage);
+	}
+	
+	return address;
+}
+
+BBString * bmx_stdc_getpeername(int socket, int * port) {
+	struct sockaddr_storage storage;
+	int len = sizeof(struct sockaddr_storage);
+	
+	BBString * address = &bbEmptyString;
+	*port = 0;
+	
+	int res = getpeername(socket, (struct sockaddr *)&storage, &len);
+	
+	if (res >= 0) {
+		if (storage.ss_family == AF_INET) {
+			*port = ((struct sockaddr_in*)&storage)->sin_port;
+		} else {
+			*port = ((struct sockaddr_in6*)&storage)->sin6_port;
+		}
+		
+		address = bmx_stdc_sockaddrestorage_address(&storage);
+	}
+	
+	return address;
+}
 
 #if _WIN32