MCPcopy Index your code
hub / github.com/RsyncProject/rsync / client_sockaddr

Function client_sockaddr

clientname.c:319–357  ·  view source on GitHub ↗

* Get the sockaddr for the client. * * If it comes in as an ipv4 address mapped into IPv6 format then we * convert it back to a regular IPv4. **/

Source from the content-addressed store, hash-verified

317 * convert it back to a regular IPv4.
318 **/
319static void client_sockaddr(int fd, struct sockaddr_storage *ss, socklen_t *ss_len)
320{
321 memset(ss, 0, sizeof *ss);
322
323 if (getpeername(fd, (struct sockaddr *) ss, ss_len)) {
324 /* FIXME: Can we really not continue? */
325 rsyserr(FLOG, errno, "getpeername on fd%d failed", fd);
326 exit_cleanup(RERR_SOCKETIO);
327 }
328
329#ifdef INET6
330 if (GET_SOCKADDR_FAMILY(ss) == AF_INET6
331 && IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)ss)->sin6_addr)) {
332 /* OK, so ss is in the IPv6 family, but it is really
333 * an IPv4 address: something like
334 * "::ffff:10.130.1.2". If we use it as-is, then the
335 * reverse lookup might fail or perhaps something else
336 * bad might happen. So instead we convert it to an
337 * equivalent address in the IPv4 address family. */
338 struct sockaddr_in6 sin6;
339 struct sockaddr_in *sin;
340
341 memcpy(&sin6, ss, sizeof sin6);
342 sin = (struct sockaddr_in *)ss;
343 memset(sin, 0, sizeof *sin);
344 sin->sin_family = AF_INET;
345 *ss_len = sizeof (struct sockaddr_in);
346#ifdef HAVE_SOCKADDR_IN_LEN
347 sin->sin_len = *ss_len;
348#endif
349 sin->sin_port = sin6.sin6_port;
350
351 /* There is a macro to extract the mapped part
352 * (IN6_V4MAPPED_TO_SINADDR ?), but it does not seem
353 * to be present in the Linux headers. */
354 memcpy(&sin->sin_addr, &sin6.sin6_addr.s6_addr[12], sizeof sin->sin_addr);
355 }
356#endif
357}
358
359
360/**

Callers 1

client_addrFunction · 0.85

Calls 1

rsyserrFunction · 0.70

Tested by

no test coverage detected