ObjFW  Diff

Differences From Artifact [8a3b636da1]:

To Artifact [488e7d77d9]:


180
181
182
183
184
185
186
187

188
189

190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207


208
209

210
211

212
213
214
215
216
217
218
219
220
221
222


223
224

225
226
227
228



229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244

245
246

247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262

263
264
265


266
267
268
269
270
271
272
273

274
275

276
277
278
279
280


281
282
283
284
285
286
287
180
181
182
183
184
185
186

187
188

189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205


206
207
208

209
210

211
212
213
214
215
216
217
218
219
220


221
222
223

224
225



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243

244
245

246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261

262
263


264
265
266
267
268
269
270
271
272

273
274

275
276
277
278


279
280
281
282
283
284
285
286
287







-
+

-
+
















-
-
+
+

-
+

-
+









-
-
+
+

-
+

-
-
-
+
+
+















-
+

-
+















-
+

-
-
+
+







-
+

-
+



-
-
+
+







@end
#endif

bool
of_udp_socket_address_equal(of_udp_socket_address_t *address1,
    of_udp_socket_address_t *address2)
{
	struct sockaddr_in *sin_1, *sin_2;
	struct sockaddr_in *addrIn1, *addrIn2;
#ifdef HAVE_IPV6
	struct sockaddr_in6 *sin6_1, *sin6_2;
	struct sockaddr_in6 *addrIn6_1, *addrIn6_2;
#endif

	if (address1->address.ss_family != address2->address.ss_family)
		return false;

	switch (address1->address.ss_family) {
	case AF_INET:
#if !defined(OF_WII) && !defined(OF_NINTENDO_3DS)
		if (address1->length < (socklen_t)sizeof(struct sockaddr_in) ||
		    address2->length < (socklen_t)sizeof(struct sockaddr_in))
			@throw [OFInvalidArgumentException exception];
#else
		if (address1->length < 8 || address2->length < 8)
			@throw [OFInvalidArgumentException exception];
#endif

		sin_1 = (struct sockaddr_in *)&address1->address;
		sin_2 = (struct sockaddr_in *)&address2->address;
		addrIn1 = (struct sockaddr_in *)&address1->address;
		addrIn2 = (struct sockaddr_in *)&address2->address;

		if (sin_1->sin_port != sin_2->sin_port)
		if (addrIn1->sin_port != addrIn2->sin_port)
			return false;
		if (sin_1->sin_addr.s_addr != sin_2->sin_addr.s_addr)
		if (addrIn1->sin_addr.s_addr != addrIn2->sin_addr.s_addr)
			return false;

		break;
#ifdef HAVE_IPV6
	case AF_INET6:
		if (address1->length < sizeof(struct sockaddr_in6) ||
		    address2->length < sizeof(struct sockaddr_in6))
			@throw [OFInvalidArgumentException exception];

		sin6_1 = (struct sockaddr_in6 *)&address1->address;
		sin6_2 = (struct sockaddr_in6 *)&address2->address;
		addrIn6_1 = (struct sockaddr_in6 *)&address1->address;
		addrIn6_2 = (struct sockaddr_in6 *)&address2->address;

		if (sin6_1->sin6_port != sin6_2->sin6_port)
		if (addrIn6_1->sin6_port != addrIn6_2->sin6_port)
			return false;
		if (memcmp(sin6_1->sin6_addr.s6_addr,
		    sin6_2->sin6_addr.s6_addr,
		    sizeof(sin6_1->sin6_addr.s6_addr)) != 0)
		if (memcmp(addrIn6_1->sin6_addr.s6_addr,
		    addrIn6_2->sin6_addr.s6_addr,
		    sizeof(addrIn6_1->sin6_addr.s6_addr)) != 0)
			return false;

		break;
#endif
	default:
		@throw [OFInvalidArgumentException exception];
	}

	return true;
}

uint32_t
of_udp_socket_address_hash(of_udp_socket_address_t *address)
{
	uint32_t hash = of_hash_seed;
	struct sockaddr_in *sin;
	struct sockaddr_in *addrIn;
#ifdef HAVE_IPV6
	struct sockaddr_in6 *sin6;
	struct sockaddr_in6 *addrIn6;
	uint32_t subhash;
#endif

	hash += address->address.ss_family;

	switch (address->address.ss_family) {
	case AF_INET:
#if !defined(OF_WII) && !defined(OF_NINTENDO_3DS)
		if (address->length < (socklen_t)sizeof(struct sockaddr_in))
			@throw [OFInvalidArgumentException exception];
#else
		if (address->length < 8)
			@throw [OFInvalidArgumentException exception];
#endif

		sin = (struct sockaddr_in *)&address->address;
		addrIn = (struct sockaddr_in *)&address->address;

		hash += (sin->sin_port << 1);
		hash ^= sin->sin_addr.s_addr;
		hash += (addrIn->sin_port << 1);
		hash ^= addrIn->sin_addr.s_addr;

		break;
#ifdef HAVE_IPV6
	case AF_INET6:
		if (address->length < sizeof(struct sockaddr_in6))
			@throw [OFInvalidArgumentException exception];

		sin6 = (struct sockaddr_in6 *)&address->address;
		addrIn6 = (struct sockaddr_in6 *)&address->address;

		hash += (sin6->sin6_port << 1);
		hash += (addrIn6->sin6_port << 1);

		OF_HASH_INIT(subhash);

		for (size_t i = 0; i < sizeof(sin6->sin6_addr.s6_addr); i++)
			OF_HASH_ADD(subhash, sin6->sin6_addr.s6_addr[i]);
		for (size_t i = 0; i < sizeof(addrIn6->sin6_addr.s6_addr); i++)
			OF_HASH_ADD(subhash, adrIn6->sin6_addr.s6_addr[i]);

		OF_HASH_FINALIZE(subhash);

		hash ^= subhash;

		break;
#endif