ObjFW  Check-in [027b704b66]

Overview
Comment:Add support for IPv6 addresses with scope
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 027b704b666286b33d30aad2569d48bbc0c96ae817dfa973d0e89c7be94035aa
User & Date: js on 2022-11-04 20:23:30
Other Links: manifest | tags
References
2022-11-04
23:32 Fixed ticket [0b30cf92a3]: Handle IPv6 addresses with scope plus 4 other changes artifact: 6ec2f37b46 user: js
Context
2022-11-04
23:25
Make Windows XP work again check-in: 631661004a user: js tags: trunk
20:23
Add support for IPv6 addresses with scope check-in: 027b704b66 user: js tags: trunk
2022-11-03
21:09
OFDNSResolverSettings: Don't assume UTF-8 check-in: cc2c113c29 user: js tags: trunk
Changes

Modified configure.ac from [339c54edb8] to [8f2d8a22b8].

1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
		AC_DEFINE(OF_HAVE_NETINET_IN_H, 1,
			[Whether we have netinet/in.h])
	])
	AC_CHECK_HEADER(netinet/tcp.h, [
		AC_DEFINE(OF_HAVE_NETINET_TCP_H, 1,
			[Whether we have netinet/tcp.h])
	])
	AC_CHECK_HEADERS([arpa/inet.h netdb.h])
	AC_CHECK_HEADER(sys/un.h, [
		AC_DEFINE(OF_HAVE_SYS_UN_H, 1, [Whether we have sys/un.h])
	])
	AC_CHECK_MEMBER([struct sockaddr_in6.sin6_addr], [
		AC_EGREP_CPP(egrep_cpp_yes, [
			#ifdef _WIN32
			typedef int BOOL;







|







1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
		AC_DEFINE(OF_HAVE_NETINET_IN_H, 1,
			[Whether we have netinet/in.h])
	])
	AC_CHECK_HEADER(netinet/tcp.h, [
		AC_DEFINE(OF_HAVE_NETINET_TCP_H, 1,
			[Whether we have netinet/tcp.h])
	])
	AC_CHECK_HEADERS([arpa/inet.h netdb.h net/if.h])
	AC_CHECK_HEADER(sys/un.h, [
		AC_DEFINE(OF_HAVE_SYS_UN_H, 1, [Whether we have sys/un.h])
	])
	AC_CHECK_MEMBER([struct sockaddr_in6.sin6_addr], [
		AC_EGREP_CPP(egrep_cpp_yes, [
			#ifdef _WIN32
			typedef int BOOL;

Modified src/OFSocket.m from [da4b96c1d5] to [4c24f8dfd3].

21
22
23
24
25
26
27




28
29
30
31
32
33
34
#define _HPUX_ALT_XOPEN_SOCKET_API

#ifdef OF_NINTENDO_3DS
# include <malloc.h>  /* For memalign() */
#endif

#include <errno.h>





#import "OFArray.h"
#import "OFCharacterSet.h"
#import "OFLocale.h"
#ifdef OF_HAVE_THREADS
# import "OFMutex.h"
#endif







>
>
>
>







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#define _HPUX_ALT_XOPEN_SOCKET_API

#ifdef OF_NINTENDO_3DS
# include <malloc.h>  /* For memalign() */
#endif

#include <errno.h>

#ifdef HAVE_NET_IF_H
# include <net/if.h>
#endif

#import "OFArray.h"
#import "OFCharacterSet.h"
#import "OFLocale.h"
#ifdef OF_HAVE_THREADS
# import "OFMutex.h"
#endif
43
44
45
46
47
48
49






50
51
52
53
54
55
56
#import "OFException.h"  /* For some E* -> WSAE* defines */
#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFLockFailedException.h"
#import "OFOutOfRangeException.h"
#import "OFUnlockFailedException.h"







#ifdef OF_AMIGAOS
# include <proto/exec.h>
#endif

#ifdef OF_NINTENDO_3DS
# include <3ds/types.h>







>
>
>
>
>
>







47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#import "OFException.h"  /* For some E* -> WSAE* defines */
#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFLockFailedException.h"
#import "OFOutOfRangeException.h"
#import "OFUnlockFailedException.h"

#ifdef OF_WINDOWS
# define interface struct
# include <netioapi.h>
# undef interface
#endif

#ifdef OF_AMIGAOS
# include <proto/exec.h>
#endif

#ifdef OF_NINTENDO_3DS
# include <3ds/types.h>
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449


450





451
452
453
454
455
456
457

OFSocketAddress
OFSocketAddressParseIPv6(OFString *IPv6, uint16_t port)
{
	void *pool = objc_autoreleasePoolPush();
	OFSocketAddress ret;
	struct sockaddr_in6 *addrIn6 = &ret.sockaddr.in6;
	size_t doubleColon;

	memset(&ret, '\0', sizeof(ret));
	ret.family = OFSocketAddressFamilyIPv6;
	ret.length = sizeof(ret.sockaddr.in6);

#ifdef AF_INET6
	addrIn6->sin6_family = AF_INET6;
#else
	addrIn6->sin6_family = AF_UNSPEC;
#endif
	addrIn6->sin6_port = OFToBigEndian16(port);

	doubleColon = [IPv6 rangeOfString: @"::"].location;








	if (doubleColon != OFNotFound) {
		OFString *left = [IPv6 substringToIndex: doubleColon];
		OFString *right = [IPv6 substringFromIndex: doubleColon + 2];
		OFArray OF_GENERIC(OFString *) *leftComponents;
		OFArray OF_GENERIC(OFString *) *rightComponents;
		size_t i;








|












|
>
>

>
>
>
>
>







439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474

OFSocketAddress
OFSocketAddressParseIPv6(OFString *IPv6, uint16_t port)
{
	void *pool = objc_autoreleasePoolPush();
	OFSocketAddress ret;
	struct sockaddr_in6 *addrIn6 = &ret.sockaddr.in6;
	size_t doubleColon, percent;

	memset(&ret, '\0', sizeof(ret));
	ret.family = OFSocketAddressFamilyIPv6;
	ret.length = sizeof(ret.sockaddr.in6);

#ifdef AF_INET6
	addrIn6->sin6_family = AF_INET6;
#else
	addrIn6->sin6_family = AF_UNSPEC;
#endif
	addrIn6->sin6_port = OFToBigEndian16(port);

	if ((percent = [IPv6 rangeOfString: @"%"].location) != OFNotFound) {
		OFString *interface = [IPv6 substringFromIndex: percent + 1];
		IPv6 = [IPv6 substringToIndex: percent];

		addrIn6->sin6_scope_id = if_nametoindex(
		    [interface cStringWithEncoding: [OFLocale encoding]]);
	}

	doubleColon = [IPv6 rangeOfString: @"::"].location;
	if (doubleColon != OFNotFound) {
		OFString *left = [IPv6 substringToIndex: doubleColon];
		OFString *right = [IPv6 substringFromIndex: doubleColon + 2];
		OFArray OF_GENERIC(OFString *) *leftComponents;
		OFArray OF_GENERIC(OFString *) *rightComponents;
		size_t i;

865
866
867
868
869
870
871









872
873
874
875
876
877
878
			[string appendFormat:
			    (first ? @"%x" : @":%x"),
			    (addrIn6->sin6_addr.s6_addr[i] << 8) |
			    addrIn6->sin6_addr.s6_addr[i + 1]];
			first = false;
		}
	}










	[string makeImmutable];

	return string;
}

OFString *







>
>
>
>
>
>
>
>
>







882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
			[string appendFormat:
			    (first ? @"%x" : @":%x"),
			    (addrIn6->sin6_addr.s6_addr[i] << 8) |
			    addrIn6->sin6_addr.s6_addr[i + 1]];
			first = false;
		}
	}

	if (addrIn6->sin6_scope_id != 0) {
		char interface[IF_NAMESIZE];

		if (if_indextoname(addrIn6->sin6_scope_id, interface) != NULL)
			[string appendFormat: @"%%%s", interface];
		else
			[string appendFormat: @"%%%u", addrIn6->sin6_scope_id];
	}

	[string makeImmutable];

	return string;
}

OFString *