ObjFW  Check-in [df7580d5e1]

Overview
Comment:Always support IPv6 addresses with numeric scope
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: df7580d5e1adac23dfc0d42853c6afaae49e26239a0c92fb7120b3dca1777eaa
User & Date: js on 2022-11-05 19:47:32
Other Links: manifest | tags
Context
2022-11-06
19:11
Remove leftover file check-in: 68652b9696 user: js tags: trunk
2022-11-05
19:47
Always support IPv6 addresses with numeric scope check-in: df7580d5e1 user: js tags: trunk
18:38
More consistency in how pragmas are used check-in: a0c049d8f1 user: js tags: trunk
Changes

Modified src/OFSocket.m from [d36d90a400] to [3facc57fe7].

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

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

#include <errno.h>

#include "platform.h"
#if defined(HAVE_NET_IF_H) && !defined(OF_MORPHOS)
# include <net/if.h>
#endif

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







<
<
<
<
<







22
23
24
25
26
27
28





29
30
31
32
33
34
35

#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
#import "OFOnce.h"
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#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







|
<
|
<







44
45
46
47
48
49
50
51

52

53
54
55
56
57
58
59
#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFLockFailedException.h"
#import "OFOutOfRangeException.h"
#import "OFUnlockFailedException.h"

#ifdef HAVE_NET_IF_H

# include <net/if.h>

#endif

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

#ifdef OF_NINTENDO_3DS
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
struct Library *SocketBase;
#  ifdef OF_AMIGAOS4
struct SocketIFace *ISocket = NULL;
#  endif
# endif
#endif

#ifdef OF_WINDOWS
static WINAPI PCHAR (*if_indextonamePtr)(NET_IFINDEX, PCHAR);
static WINAPI NET_IFINDEX (*if_nametoindexPtr)(PCSTR);
#endif

#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS)
OF_CONSTRUCTOR()
{
	if (OFTLSKeyNew(&OFSocketBaseKey) != 0)
		@throw [OFInitializationFailedException exception];

# ifdef OF_AMIGAOS4
	if (OFTLSKeyNew(&OFSocketInterfaceKey) != 0)
		@throw [OFInitializationFailedException exception];
# endif
}
#endif

#if !defined(OF_AMIGAOS) || defined(OF_MORPHOS) || !defined(OF_HAVE_THREADS)
static void
init(void)
{
# if defined(OF_WINDOWS)
	WSADATA wsa;
	HMODULE module;

	if (WSAStartup(MAKEWORD(2, 0), &wsa))
		return;

	if ((module = LoadLibrary("iphlpapi.dll")) != NULL) {
		if_indextonamePtr = (WINAPI PCHAR (*)(NET_IFINDEX, PCHAR))
		    GetProcAddress(module, "if_indextoname");
		if_nametoindexPtr = (WINAPI NET_IFINDEX (*)(PCSTR))
		    GetProcAddress(module, "if_nametoindex");
	}
# elif defined(OF_AMIGAOS)
	if ((SocketBase = OpenLibrary("bsdsocket.library", 4)) == NULL)
		return;

#  ifdef OF_AMIGAOS4
	if ((ISocket = (struct SocketIFace *)
	    GetInterface(SocketBase, "main", 1, NULL)) == NULL) {







<
<
<
<
<



















<



<
<
<
<
<
<
<







90
91
92
93
94
95
96





97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

116
117
118







119
120
121
122
123
124
125
struct Library *SocketBase;
#  ifdef OF_AMIGAOS4
struct SocketIFace *ISocket = NULL;
#  endif
# endif
#endif






#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS)
OF_CONSTRUCTOR()
{
	if (OFTLSKeyNew(&OFSocketBaseKey) != 0)
		@throw [OFInitializationFailedException exception];

# ifdef OF_AMIGAOS4
	if (OFTLSKeyNew(&OFSocketInterfaceKey) != 0)
		@throw [OFInitializationFailedException exception];
# endif
}
#endif

#if !defined(OF_AMIGAOS) || defined(OF_MORPHOS) || !defined(OF_HAVE_THREADS)
static void
init(void)
{
# if defined(OF_WINDOWS)
	WSADATA wsa;


	if (WSAStartup(MAKEWORD(2, 0), &wsa))
		return;







# elif defined(OF_AMIGAOS)
	if ((SocketBase = OpenLibrary("bsdsocket.library", 4)) == NULL)
		return;

#  ifdef OF_AMIGAOS4
	if ((ISocket = (struct SocketIFace *)
	    GetInterface(SocketBase, "main", 1, NULL)) == NULL) {
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482

483
484
485
486




487
488
489
490
491
492
493
	addrIn6->sin6_family = AF_INET6;
#else
	addrIn6->sin6_family = AF_UNSPEC;
#endif
	addrIn6->sin6_port = OFToBigEndian16(port);

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

#if defined(OF_WINDOWS)
		if (if_nametoindexPtr != NULL)
			addrIn6->sin6_scope_id = if_nametoindexPtr([interface
			    cStringWithEncoding: [OFLocale encoding]]);

#elif defined(HAVE_IF_NAMETOINDEX)
		addrIn6->sin6_scope_id = if_nametoindex(
		    [interface cStringWithEncoding: [OFLocale encoding]]);
#endif




	}

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







<

<


<
|
|
|
>
|
|
|

>
>
>
>







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
475
	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];


		@try {
			addrIn6->sin6_scope_id = (uint32_t)[interface
			    unsignedLongLongValueWithBase: 10];
		} @catch (OFInvalidFormatException *e) {
#if defined(HAVE_IF_NAMETOINDEX) && !defined(OF_WINDOWS)
			addrIn6->sin6_scope_id = if_nametoindex([interface
			    cStringWithEncoding: [OFLocale encoding]]);
#endif
		}

		if (addrIn6->sin6_scope_id == 0)
			@throw [OFInvalidArgumentException exception];
	}

	doubleColon = [IPv6 rangeOfString: @"::"].location;
	if (doubleColon != OFNotFound) {
		OFString *left = [IPv6 substringToIndex: doubleColon];
		OFString *right = [IPv6 substringFromIndex: doubleColon + 2];
		OFArray OF_GENERIC(OFString *) *leftComponents;
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925

926
927
928
929
930
931
932
933
934
935
			    (first ? @"%x" : @":%x"),
			    (addrIn6->sin6_addr.s6_addr[i] << 8) |
			    addrIn6->sin6_addr.s6_addr[i + 1]];
			first = false;
		}
	}

#if defined(HAVE_IF_INDEXTONAME) || defined(OF_WINDOWS)
	if (addrIn6->sin6_scope_id != 0) {
# ifdef OF_WINDOWS
		char interface[IF_MAX_STRING_SIZE];

		if (if_indextonamePtr != NULL && if_indextonamePtr(
		    addrIn6->sin6_scope_id, interface) != NULL)
# else
		char interface[IF_NAMESIZE];

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

			[string appendFormat: @"%%%u", addrIn6->sin6_scope_id];
	}
#endif

	[string makeImmutable];

	return string;
}

OFString *







<

<
<
|
<
<
<



<


>


<







887
888
889
890
891
892
893

894


895



896
897
898

899
900
901
902
903

904
905
906
907
908
909
910
			    (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) {


#if defined(HAVE_IF_INDEXTONAME) && !defined(OF_WINDOWS)



		char interface[IF_NAMESIZE];

		if (if_indextoname(addrIn6->sin6_scope_id, interface) != NULL)

			[string appendFormat: @"%%%s", interface];
		else
# endif
			[string appendFormat: @"%%%u", addrIn6->sin6_scope_id];
	}


	[string makeImmutable];

	return string;
}

OFString *