Code Monkey home page Code Monkey logo

Comments (4)

zytzjx avatar zytzjx commented on August 17, 2024

I don't have update for long time .Now I compile libimobiledevice failed. I need some times to check

from winlibimobiledevice.

vipinbeni avatar vipinbeni commented on August 17, 2024

@zytzjx Thanks for your kind Reply please update me if any solution found at your end

Thanks a lot

from winlibimobiledevice.

zytzjx avatar zytzjx commented on August 17, 2024

today, I compiled. I have modified some code for libimobiledevice\common socket.c. others step is same.
I use the newest msys2. trust me , try it

/*

  • socket.c
  • Copyright (C) 2012-2020 Nikias Bassen [email protected]
  • Copyright (C) 2012 Martin Szulecki [email protected]
  • This library is free software; you can redistribute it and/or
  • modify it under the terms of the GNU Lesser General Public
  • License as published by the Free Software Foundation; either
  • version 2.1 of the License, or (at your option) any later version.
  • This library is distributed in the hope that it will be useful,
  • but WITHOUT ANY WARRANTY; without even the implied warranty of
  • MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  • Lesser General Public License for more details.
  • You should have received a copy of the GNU Lesser General Public
  • License along with this library; if not, write to the Free Software
  • Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
    */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/stat.h>
#ifdef WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#ifndef HAVE_GETIFADDRS
#include <iphlpapi.h>
#endif
static int wsa_init = 0;
#ifndef IFF_RUNNING
#define IFF_RUNNING IFF_UP
#endif
#ifndef AI_NUMERICSERV
#define AI_NUMERICSERV 0
#endif
#else
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <fcntl.h>
#ifdef AF_INET6
#include <net/if.h>
#include <ifaddrs.h>
#endif
#endif
#include "socket.h"

#define RECV_TIMEOUT 20000
#define CONNECT_TIMEOUT 5000

#ifndef EAFNOSUPPORT
#define EAFNOSUPPORT 102
#endif
#ifndef ECONNRESET
#define ECONNRESET 108
#endif
#ifndef ETIMEDOUT
#define ETIMEDOUT 138
#endif

static int verbose = 0;

void socket_set_verbose(int level)
{
verbose = level;
}

const char *socket_addr_to_string(struct sockaddr *addr, char *addr_out, size_t addr_out_size)
{
#ifdef WIN32
WSADATA wsa_data;
if (!wsa_init) {
if (WSAStartup(MAKEWORD(2,2), &wsa_data) != ERROR_SUCCESS) {
fprintf(stderr, "WSAStartup failed!\n");
ExitProcess(-1);
}
wsa_init = 1;
}
DWORD addr_out_len = addr_out_size;
DWORD addrlen = 0;

if (addr->sa_family == AF_INET) {
	addrlen = sizeof(struct sockaddr_in);
}

#ifdef AF_INET6
else if (addr->sa_family == AF_INET6) {
addrlen = sizeof(struct sockaddr_in6);
}
#endif
else {
errno = EAFNOSUPPORT;
return NULL;
}

if (WSAAddressToString(addr, addrlen, NULL, addr_out, &addr_out_len) == 0) {
	return addr_out;
}

#else
const void *addrdata = NULL;

if (addr->sa_family == AF_INET) {
	addrdata = &((struct sockaddr_in*)addr)->sin_addr;
}

#ifdef AF_INET6
else if (addr->sa_family == AF_INET6) {
addrdata = &((struct sockaddr_in6*)addr)->sin6_addr;
}
#endif
else {
errno = EAFNOSUPPORT;
return NULL;
}

if (inet_ntop(addr->sa_family, addrdata, addr_out, addr_out_size)) {
	return addr_out;
}

#endif
return NULL;
}

#ifndef WIN32
int socket_create_unix(const char *filename)
{
struct sockaddr_un name;
int sock;
#ifdef SO_NOSIGPIPE
int yes = 1;
#endif

// remove if still present
unlink(filename);

/* Create the socket. */
sock = socket(PF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
	perror("socket");
	return -1;
}

#ifdef SO_NOSIGPIPE
if (setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, (void*)&yes, sizeof(int)) == -1) {
perror("setsockopt()");
socket_close(sock);
return -1;
}
#endif

/* Bind a name to the socket. */
name.sun_family = AF_UNIX;
strncpy(name.sun_path, filename, sizeof(name.sun_path));
name.sun_path[sizeof(name.sun_path) - 1] = '\0';

if (bind(sock, (struct sockaddr*)&name, sizeof(name)) < 0) {
	perror("bind");
	socket_close(sock);
	return -1;
}

if (listen(sock, 10) < 0) {
	perror("listen");
	socket_close(sock);
	return -1;
}

return sock;

}

int socket_connect_unix(const char *filename)
{
struct sockaddr_un name;
int sfd = -1;
struct stat fst;
#ifdef SO_NOSIGPIPE
int yes = 1;
#endif
int bufsize = 0x20000;

// check if socket file exists...
if (stat(filename, &fst) != 0) {
	if (verbose >= 2)
		fprintf(stderr, "%s: stat '%s': %s\n", __func__, filename,
				strerror(errno));
	return -1;
}
// ... and if it is a unix domain socket
if (!S_ISSOCK(fst.st_mode)) {
	if (verbose >= 2)
		fprintf(stderr, "%s: File '%s' is not a socket!\n", __func__,
				filename);
	return -1;
}
// make a new socket
if ((sfd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
	if (verbose >= 2)
		fprintf(stderr, "%s: socket: %s\n", __func__, strerror(errno));
	return -1;
}

if (setsockopt(sfd, SOL_SOCKET, SO_SNDBUF, (void*)&bufsize, sizeof(int)) == -1) {
	perror("Could not set send buffer for socket");
}

if (setsockopt(sfd, SOL_SOCKET, SO_RCVBUF, (void*)&bufsize, sizeof(int)) == -1) {
	perror("Could not set receive buffer for socket");
}

#ifdef SO_NOSIGPIPE
if (setsockopt(sfd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&yes, sizeof(int)) == -1) {
perror("setsockopt()");
socket_close(sfd);
return -1;
}
#endif
// and connect to 'filename'
name.sun_family = AF_UNIX;
strncpy(name.sun_path, filename, sizeof(name.sun_path));
name.sun_path[sizeof(name.sun_path) - 1] = 0;

int flags = fcntl(sfd, F_GETFL, 0);
fcntl(sfd, F_SETFL, flags | O_NONBLOCK);

do {
	if (connect(sfd, (struct sockaddr*)&name, sizeof(name)) != -1) {
		break;
	}
	if (errno == EINPROGRESS) {
		fd_set fds;
		FD_ZERO(&fds);
		FD_SET(sfd, &fds);

		struct timeval timeout;
		timeout.tv_sec = CONNECT_TIMEOUT / 1000;
		timeout.tv_usec = (CONNECT_TIMEOUT - (timeout.tv_sec * 1000)) * 1000;
		if (select(sfd + 1, NULL, &fds, NULL, &timeout) == 1) {
			int so_error;
			socklen_t len = sizeof(so_error);
			getsockopt(sfd, SOL_SOCKET, SO_ERROR, (void*)&so_error, &len);
			if (so_error == 0) {
				break;
			}
		}
	}
	socket_close(sfd);
	sfd = -1;
} while (0);

if (sfd < 0) {
	if (verbose >= 2)
		fprintf(stderr, "%s: connect: %s\n", __func__, strerror(errno));
	return -1;
}

return sfd;

}
#endif

int socket_create(uint16_t port)
{
int sfd = -1;
int yes = 1;
#ifdef WIN32
WSADATA wsa_data;
if (!wsa_init) {
if (WSAStartup(MAKEWORD(2,2), &wsa_data) != ERROR_SUCCESS) {
fprintf(stderr, "WSAStartup failed!\n");
ExitProcess(-1);
}
wsa_init = 1;
}
#endif
struct sockaddr_in saddr;

if (0 > (sfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))) {
	perror("socket()");
	return -1;
}

if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(int)) == -1) {
	perror("setsockopt()");
	socket_close(sfd);
	return -1;
}

#ifdef SO_NOSIGPIPE
if (setsockopt(sfd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&yes, sizeof(int)) == -1) {
perror("setsockopt()");
socket_close(sfd);
return -1;
}
#endif

memset((void *) &saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
saddr.sin_port = htons(port);

if (0 > bind(sfd, (struct sockaddr *) &saddr, sizeof(saddr))) {
	perror("bind()");
	socket_close(sfd);
	return -1;
}

if (listen(sfd, 1) == -1) {
	perror("listen()");
	socket_close(sfd);
	return -1;
}

return sfd;

}

#ifdef AF_INET6
static uint32_t _in6_addr_scope(struct in6_addr* addr)
{
uint32_t scope = 0;

if (IN6_IS_ADDR_MULTICAST(addr)) {
	if (IN6_IS_ADDR_MC_NODELOCAL(addr)) {
		scope = 1;
	} else if (IN6_IS_ADDR_MC_LINKLOCAL(addr)) {
		scope = 2;
	} else if (IN6_IS_ADDR_MC_SITELOCAL(addr)) {
		scope = 5;
	}

	return scope;
}

if (IN6_IS_ADDR_LINKLOCAL(addr)) {
	scope = 2;
} else if (IN6_IS_ADDR_LOOPBACK(addr)) {
	scope = 2;
} else if (IN6_IS_ADDR_SITELOCAL(addr)) {
	scope = 5;
} else if (IN6_IS_ADDR_UNSPECIFIED(addr)) {
	scope = 0;
}

return scope;

}

#ifndef HAVE_GETIFADDRS
#ifdef WIN32

struct ifaddrs {
struct ifaddrs ifa_next; / Next item in list */
char ifa_name; / Name of interface /
unsigned int ifa_flags; /
Flags from SIOCGIFFLAGS */
struct sockaddr ifa_addr; / Address of interface */
struct sockaddr ifa_netmask; / Netmask of interface */
union {
struct sockaddr ifu_broadaddr; / Broadcast address of interface */
struct sockaddr ifu_dstaddr; / Point-to-point destination address */
} ifa_ifu;
#define ifa_broadaddr ifa_ifu.ifu_broadaddr
#define ifa_dstaddr ifa_ifu.ifu_dstaddr
void ifa_data; / Address-specific data */
};

#define WORKING_BUFFER_SIZE 15000
#define MAX_TRIES 3

static void freeifaddrs(struct ifaddrs *ifa)
{
if (!ifa) {
return;
}
free(ifa->ifa_name);
free(ifa->ifa_addr);
free(ifa->ifa_netmask);
free(ifa->ifa_dstaddr);
freeifaddrs(ifa->ifa_next);
free(ifa);
}

/*

  • getifaddrs() reference implementation for win32.

  • Heavily based on openpgm's implementation found here:

  • https://github.com/steve-o/openpgm/blob/master/openpgm/pgm/getifaddrs.c
    /
    static int getifaddrs(struct ifaddrs
    * ifap)
    {
    struct ifaddrs* ifa = NULL;

    DWORD dwRetVal = 0;

    PIP_ADAPTER_ADDRESSES pAddresses = NULL;
    ULONG outBufLen = 0;
    ULONG Iterations = 0;

    ULONG flags = GAA_FLAG_INCLUDE_PREFIX |
    GAA_FLAG_SKIP_ANYCAST |
    GAA_FLAG_SKIP_DNS_SERVER |
    GAA_FLAG_SKIP_FRIENDLY_NAME |
    GAA_FLAG_SKIP_MULTICAST;

    PIP_ADAPTER_ADDRESSES adapter = NULL;

    if (!ifap) {
    errno = EINVAL;
    return -1;
    }
    *ifap = NULL;

    outBufLen = WORKING_BUFFER_SIZE;
    do {
    pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
    if (pAddresses == NULL) {
    printf("Memory allocation failed for IP_ADAPTER_ADDRESSES struct\n");
    return -1;
    }
    dwRetVal = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAddresses, &outBufLen);
    if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
    free(pAddresses);
    pAddresses = NULL;
    } else {
    break;
    }
    Iterations++;
    } while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < MAX_TRIES));

    if (dwRetVal != NO_ERROR) {
    free(pAddresses);
    return -1;
    }

    for (adapter = pAddresses; adapter; adapter = adapter->Next) {
    int unicastIndex = 0;
    for (IP_ADAPTER_UNICAST_ADDRESS unicast = adapter->FirstUnicastAddress; unicast; unicast = unicast->Next, ++unicastIndex) {
    /
    ensure IP adapter */
    if (AF_INET != unicast->Address.lpSockaddr->sa_family && AF_INET6 != unicast->Address.lpSockaddr->sa_family) {
    continue;
    }

     	if (!ifa) {
     		ifa = malloc(sizeof(struct ifaddrs));
     		if (!ifa) {
     			errno = ENOMEM;
     			free(pAddresses);
     			return -1;
     		}
     		*ifap = ifa;
     		ifa->ifa_next = NULL;
     	} else {
     		struct ifaddrs* ifanew = malloc(sizeof(struct ifaddrs));
     		if (!ifanew) {
     			freeifaddrs(*ifap);
     			free(pAddresses);
     			errno = ENOMEM;
     			return -1;
     		}
     		ifa->ifa_next = ifanew;
     		ifa = ifanew;
     		ifa->ifa_next = NULL;
     	}
    
     	/* name */
     	ifa->ifa_name = strdup(adapter->AdapterName);
    
     	/* flags */
     	ifa->ifa_flags = 0;
     	if (IfOperStatusUp == adapter->OperStatus)
     		ifa->ifa_flags |= IFF_UP;
     	if (IF_TYPE_SOFTWARE_LOOPBACK == adapter->IfType)
     		ifa->ifa_flags |= IFF_LOOPBACK;
     	if (!(adapter->Flags & IP_ADAPTER_NO_MULTICAST))
     		ifa->ifa_flags |= IFF_MULTICAST;
    
     	/* address */
     	ifa->ifa_addr = (struct sockaddr*)malloc(sizeof(struct sockaddr_storage));
     	memcpy(ifa->ifa_addr, unicast->Address.lpSockaddr, unicast->Address.iSockaddrLength);
    
     	/* netmask */
     	ifa->ifa_netmask = (struct sockaddr*)malloc(sizeof(struct sockaddr_storage));
     	memset(ifa->ifa_netmask, 0, sizeof(struct sockaddr_storage));
    

/* pre-Vista must hunt for matching prefix in linked list, otherwise use

  • OnLinkPrefixLength from IP_ADAPTER_UNICAST_ADDRESS structure.
  • FirstPrefix requires Windows XP SP1, from SP1 to pre-Vista provides a
  • single adapter prefix for each IP address. Vista and later provides
  • host IP address prefix, subnet IP address, and subnet broadcast IP
  • address. In addition there is a multicast and broadcast address prefix.
    */
    ULONG prefixLength = 0;

#if defined( _WIN32 ) && ( _WIN32_WINNT >= 0x0600 )
/* For a unicast IPv4 address, any value greater than 32 is an illegal

  • value. For a unicast IPv6 address, any value greater than 128 is an
  • illegal value. A value of 255 is commonly used to represent an illegal
  • value.
  • Windows 7 SP1 returns 64 for Teredo links which is incorrect.
    */

#define IN6_IS_ADDR_TEREDO(addr)
(((const uint32_t *)(addr))[0] == ntohl (0x20010000))

		if (AF_INET6 == unicast->Address.lpSockaddr->sa_family &&

/* TunnelType only applies to one interface on the adapter and no

  • convenient method is provided to determine which.
    /
    TUNNEL_TYPE_TEREDO == adapter->TunnelType &&
    /
    Test the interface with the known Teredo network prefix.
    /
    IN6_IS_ADDR_TEREDO( &((struct sockaddr_in6
    )(unicast->Address.lpSockaddr))->sin6_addr) &&
    /* Test that this version is actually wrong, subsequent releases from Microsoft
  • may resolve the issue.
    /
    32 != unicast->OnLinkPrefixLength)
    {
    prefixLength = 32;
    }
    else
    prefixLength = unicast->OnLinkPrefixLength;
    #else
    /
    The order of linked IP_ADAPTER_UNICAST_ADDRESS structures pointed to by
  • the FirstUnicastAddress member does not have any relationship with the
  • order of linked IP_ADAPTER_PREFIX structures pointed to by the FirstPrefix
  • member.
  • Example enumeration:
  • [ no subnet ]
  • ::1/128 - address
  • ff00::%1/8 - multicast (no IPv6 broadcast)
  • 127.0.0.0/8 - subnet
  • 127.0.0.1/32 - address
  • 127.255.255.255/32 - subnet broadcast
  • 224.0.0.0/4 - multicast
  • 255.255.255.255/32 - broadcast
  • Which differs from most adapters listing three IPv6:
  • fe80::%10/64 - subnet
  • fe80::51e9:5fe5:4202:325a%10/128 - address
  • ff00::%10/8 - multicast
  • !IfOperStatusUp IPv4 addresses are skipped:
  • fe80::%13/64 - subnet
  • fe80::d530:946d:e8df:8c91%13/128 - address
  • ff00::%13/8 - multicast
  • [ no subnet ]
  • [ no address ]
  • 224.0.0.0/4 - multicast
  • 255.255.255.255/32 - broadcast
  • On PTP links no multicast or broadcast addresses are returned:
  • [ no subnet ]
  • fe80::5efe:10.203.9.30/128 - address
  • [ no multicast ]
  • [ no multicast ]
  • [ no broadcast ]
  • Active primary IPv6 interfaces are a bit overloaded:
  • ::/0 - default route
  • 2001::/32 - global subnet
  • 2001:0:4137:9e76:2443:d6:ba87:1a2a/128 - global address
  • fe80::/64 - link-local subnet
  • fe80::2443:d6:ba87:1a2a/128 - link-local address
  • ff00::/8 - multicast
    */

#define IN_LINKLOCAL(a) ((((uint32_t) (a)) & 0xaffff0000) == 0xa9fe0000)

		for (IP_ADAPTER_PREFIX *prefix = adapter->FirstPrefix; prefix; prefix = prefix->Next) {
			LPSOCKADDR lpSockaddr = prefix->Address.lpSockaddr;
			if (lpSockaddr->sa_family != unicast->Address.lpSockaddr->sa_family)
				continue;

/* special cases /
/
RFC2863: IPv4 interface not up /
if (AF_INET == lpSockaddr->sa_family && adapter->OperStatus != IfOperStatusUp) {
/
RFC3927: link-local IPv4 always has 16-bit CIDR /
if (IN_LINKLOCAL( ntohl (((struct sockaddr_in
)(unicast->Address.lpSockaddr))->sin_addr.s_addr))) {
prefixLength = 16;
}
break;
}
/* default IPv6 route /
if (AF_INET6 == lpSockaddr->sa_family && 0 == prefix->PrefixLength && IN6_IS_ADDR_UNSPECIFIED( &((struct sockaddr_in6
)(lpSockaddr))->sin6_addr)) {
continue;
}
/* Assume unicast address for first prefix of operational adapter /
if (AF_INET == lpSockaddr->sa_family)
if (IN_MULTICAST( ntohl (((struct sockaddr_in
)(lpSockaddr))->sin_addr.s_addr))) {
fprintf(stderr, "FATAL: first prefix is non a unicast address\n");
break;
}
if (AF_INET6 == lpSockaddr->sa_family)
if (IN6_IS_ADDR_MULTICAST( &((struct sockaddr_in6*)(lpSockaddr))->sin6_addr)) {
fprintf(stderr, "FATAL: first prefix is not a unicast address\n");
break;
}
/* Assume subnet or host IP address for XP backward compatibility */

			prefixLength = prefix->PrefixLength;
			break;
		}

#endif /* defined( _WIN32 ) && ( _WIN32_WINNT >= 0x0600 ) */

/* map prefix to netmask /
ifa->ifa_netmask->sa_family = unicast->Address.lpSockaddr->sa_family;
switch (unicast->Address.lpSockaddr->sa_family) {
case AF_INET:
if (0 == prefixLength || prefixLength > 32) {
prefixLength = 32;
}
#if defined( _WIN32) && ( _WIN32_WINNT >= 0x0600 )
/
Added in Vista, but no IPv6 equivalent. /
{
ULONG Mask;
ConvertLengthToIpv4Mask (prefixLength, &Mask);
((struct sockaddr_in
)ifa->ifa_netmask)->sin_addr.s_addr = Mask; /* network order /
}
#else
/
NB: left-shift of full bit-width is undefined in C standard. /
((struct sockaddr_in
)ifa->ifa_netmask)->sin_addr.s_addr = htonl( 0xffffffffU << ( 32 - prefixLength ) );
#endif
break;

		case AF_INET6:
			if (0 == prefixLength || prefixLength > 128) {
				prefixLength = 128;
			}
			for (LONG i = prefixLength, j = 0; i > 0; i -= 8, ++j) {
				((struct sockaddr_in6*)ifa->ifa_netmask)->sin6_addr.s6_addr[ j ] = i >= 8 ? 0xff : (ULONG)(( 0xffU << ( 8 - i ) ) & 0xffU );
			}
			break;
		default:
			break;
		}
	}
}
free(pAddresses);

return 0;

}
#else
#error No reference implementation for getifaddrs available for this platform.
#endif
#endif

static int32_t _sockaddr_in6_scope_id(struct sockaddr_in6* addr)
{
int32_t res = -1;
struct ifaddrs *ifaddr=NULL, *ifa=NULL;
uint32_t addr_scope;

/* get scope for requested address */
addr_scope = _in6_addr_scope(&addr->sin6_addr);
if (addr_scope == 0) {
	/* global scope doesn't need a specific scope id */
	return addr_scope;
}

/* get interfaces */
if (getifaddrs(&ifaddr) == -1) {
	perror("getifaddrs");
	return res;
}

/* loop over interfaces */
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
	/* skip if no address is available */
	if (ifa->ifa_addr == NULL) {
		continue;
	}

	/* skip if wrong family */
	if (ifa->ifa_addr->sa_family != AF_INET6) {
		continue;
	}

	/* skip if not up */
	if ((ifa->ifa_flags & IFF_UP) == 0) {
		continue;
	}

	/* skip if not running */
	if ((ifa->ifa_flags & IFF_RUNNING) == 0) {
		continue;
	}

	struct sockaddr_in6* addr_in = (struct sockaddr_in6*)ifa->ifa_addr;

	/* skip if scopes do not match */
	if (_in6_addr_scope(&addr_in->sin6_addr) != addr_scope) {
		continue;
	}

	/* use if address is equal */
	if (memcmp(&addr->sin6_addr.s6_addr, &addr_in->sin6_addr.s6_addr, sizeof(addr_in->sin6_addr.s6_addr)) == 0) {
		/* if scope id equals the requested one then assume it was valid */
		if (addr->sin6_scope_id == addr_in->sin6_scope_id) {
			res = addr_in->sin6_scope_id;
			break;
		} else {
			if ((addr_in->sin6_scope_id > addr->sin6_scope_id) && (res >= 0)) {
				// use last valid scope id as we're past the requested scope id
				break;
			}
			res = addr_in->sin6_scope_id;
			continue;
		}
	}

	/* skip loopback interface if not already matched exactly above */
	if ((ifa->ifa_flags & IFF_LOOPBACK) != 0) {
		continue;
	}

	if ((addr_in->sin6_scope_id > addr->sin6_scope_id) && (res >= 0)) {
		// use last valid scope id as we're past the requested scope id
		break;
	}

	res = addr_in->sin6_scope_id;

	/* if scope id equals the requested one then assume it was valid */
	if (addr->sin6_scope_id == addr_in->sin6_scope_id) {
		/* set the scope id of this interface as most likely candidate */
		break;
	}
}

freeifaddrs(ifaddr);

return res;

}
#endif

int socket_connect_addr(struct sockaddr* addr, uint16_t port)
{
int sfd = -1;
int yes = 1;
int bufsize = 0x20000;
int addrlen = 0;
#ifdef WIN32
u_long l_yes = 1;
WSADATA wsa_data;
if (!wsa_init) {
if (WSAStartup(MAKEWORD(2,2), &wsa_data) != ERROR_SUCCESS) {
fprintf(stderr, "WSAStartup failed!\n");
ExitProcess(-1);
}
wsa_init = 1;
}
#endif

if (addr->sa_family == AF_INET) {
	struct sockaddr_in* addr_in = (struct sockaddr_in*)addr;
	addr_in->sin_port = htons(port);
	addrlen = sizeof(struct sockaddr_in);
}

#ifdef AF_INET6
else if (addr->sa_family == AF_INET6) {
struct sockaddr_in6* addr_in = (struct sockaddr_in6*)addr;
addr_in->sin6_port = htons(port);

	/*
	 * IPv6 Routing Magic:
	 *
	 * If the scope of the address is a link-local one, IPv6 requires the
	 * scope id set to an interface number to allow proper routing. However,
	 * as the provided sockaddr might contain a wrong scope id, we must find
	 * a scope id from a suitable interface on this system or routing might
	 * fail. An IPv6 guru should have another look though...
	 */
	addr_in->sin6_scope_id = _sockaddr_in6_scope_id(addr_in);

	addrlen = sizeof(struct sockaddr_in6);
}

#endif
else {
fprintf(stderr, "ERROR: Unsupported address family");
return -1;
}

sfd = socket(addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
if (sfd == -1) {
	perror("socket()");
	return -1;
}

#ifdef SO_NOSIGPIPE
if (setsockopt(sfd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&yes, sizeof(int)) == -1) {
perror("setsockopt()");
socket_close(sfd);
return -1;
}
#endif

if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(int)) == -1) {
	perror("setsockopt()");
	socket_close(sfd);
	return -1;
}

#ifdef WIN32
ioctlsocket(sfd, FIONBIO, &l_yes);
#else
int flags = fcntl(sfd, F_GETFL, 0);
fcntl(sfd, F_SETFL, flags | O_NONBLOCK);
#endif

do {
	if (connect(sfd, addr, addrlen) != -1) {
		break;
	}

#ifdef WIN32
if (WSAGetLastError() == WSAEWOULDBLOCK)
#else
if (errno == EINPROGRESS)
#endif
{
fd_set fds;
FD_ZERO(&fds);
FD_SET(sfd, &fds);

		struct timeval timeout;
		timeout.tv_sec = CONNECT_TIMEOUT / 1000;
		timeout.tv_usec = (CONNECT_TIMEOUT - (timeout.tv_sec * 1000)) * 1000;
		if (select(sfd + 1, NULL, &fds, NULL, &timeout) == 1) {
			int so_error;
			socklen_t len = sizeof(so_error);
			getsockopt(sfd, SOL_SOCKET, SO_ERROR, (void*)&so_error, &len);
			if (so_error == 0) {
				errno = 0;
				break;
			}
			errno = so_error;
		}
	}
	socket_close(sfd);
	sfd = -1;
} while (0);

if (sfd < 0) {
	if (verbose >= 2) {
		char addrtxt[48];
		socket_addr_to_string(addr, addrtxt, sizeof(addrtxt));
		fprintf(stderr, "%s: Could not connect to %s port %d\n", __func__, addrtxt, port);
	}
	return -1;
}

if (setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, (void*)&yes, sizeof(int)) == -1) {
	perror("Could not set TCP_NODELAY on socket");
}

if (setsockopt(sfd, SOL_SOCKET, SO_SNDBUF, (void*)&bufsize, sizeof(int)) == -1) {
	perror("Could not set send buffer for socket");
}

if (setsockopt(sfd, SOL_SOCKET, SO_RCVBUF, (void*)&bufsize, sizeof(int)) == -1) {
	perror("Could not set receive buffer for socket");
}

return sfd;

}

int socket_connect(const char *addr, uint16_t port)
{
int sfd = -1;
int yes = 1;
int bufsize = 0x20000;
struct addrinfo hints;
struct addrinfo *result, *rp;
char portstr[8];
int res;
#ifdef WIN32
u_long l_yes = 1;
WSADATA wsa_data;
if (!wsa_init) {
if (WSAStartup(MAKEWORD(2,2), &wsa_data) != ERROR_SUCCESS) {
fprintf(stderr, "WSAStartup failed!\n");
ExitProcess(-1);
}
wsa_init = 1;
}
#else
int flags = 0;
#endif

if (!addr) {
	errno = EINVAL;
	return -1;
}

memset(&hints, '\0', sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = 0;
hints.ai_protocol = IPPROTO_TCP;

sprintf(portstr, "%d", port);

res = getaddrinfo(addr, portstr, &hints, &result);
if (res != 0) {
	fprintf(stderr, "%s: getaddrinfo: %s\n", __func__, gai_strerror(res));
	return -1;
}

for (rp = result; rp != NULL; rp = rp->ai_next) {
	sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
	if (sfd == -1) {
		continue;
	}

#ifdef SO_NOSIGPIPE
if (setsockopt(sfd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&yes, sizeof(int)) == -1) {
perror("setsockopt()");
socket_close(sfd);
return -1;
}
#endif

	if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(int)) == -1) {
		perror("setsockopt()");
		socket_close(sfd);
		continue;
	}

#ifdef WIN32
ioctlsocket(sfd, FIONBIO, &l_yes);
#else
flags = fcntl(sfd, F_GETFL, 0);
fcntl(sfd, F_SETFL, flags | O_NONBLOCK);
#endif

	if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1) {
		break;
	}

#ifdef WIN32
if (WSAGetLastError() == WSAEWOULDBLOCK)
#else
if (errno == EINPROGRESS)
#endif
{
fd_set fds;
FD_ZERO(&fds);
FD_SET(sfd, &fds);

		struct timeval timeout;
		timeout.tv_sec = CONNECT_TIMEOUT / 1000;
		timeout.tv_usec = (CONNECT_TIMEOUT - (timeout.tv_sec * 1000)) * 1000;
		if (select(sfd + 1, NULL, &fds, NULL, &timeout) == 1) {
			int so_error;
			socklen_t len = sizeof(so_error);
			getsockopt(sfd, SOL_SOCKET, SO_ERROR, (void*)&so_error, &len);
			if (so_error == 0) {
				break;
			}
		}
	}
	socket_close(sfd);
}

freeaddrinfo(result);

if (rp == NULL) {
	if (verbose >= 2)
		fprintf(stderr, "%s: Could not connect to %s:%d\n", __func__, addr, port);
	return -1;
}

if (setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, (void*)&yes, sizeof(int)) == -1) {
	perror("Could not set TCP_NODELAY on socket");
}

if (setsockopt(sfd, SOL_SOCKET, SO_SNDBUF, (void*)&bufsize, sizeof(int)) == -1) {
	perror("Could not set send buffer for socket");
}

if (setsockopt(sfd, SOL_SOCKET, SO_RCVBUF, (void*)&bufsize, sizeof(int)) == -1) {
	perror("Could not set receive buffer for socket");
}

return sfd;

}

int socket_check_fd(int fd, fd_mode fdm, unsigned int timeout)
{
fd_set fds;
int sret;
int eagain;
struct timeval to;
struct timeval *pto;

if (fd < 0) {
	if (verbose >= 2)
		fprintf(stderr, "ERROR: invalid fd in check_fd %d\n", fd);
	return -1;
}

FD_ZERO(&fds);
FD_SET(fd, &fds);

sret = -1;

do {
	if (timeout > 0) {
		to.tv_sec = (time_t) (timeout / 1000);
		to.tv_usec = (time_t) ((timeout - (to.tv_sec * 1000)) * 1000);
		pto = &to;
	} else {
		pto = NULL;
	}
	eagain = 0;
	switch (fdm) {
	case FDM_READ:
		sret = select(fd + 1, &fds, NULL, NULL, pto);
		break;
	case FDM_WRITE:
		sret = select(fd + 1, NULL, &fds, NULL, pto);
		break;
	case FDM_EXCEPT:
		sret = select(fd + 1, NULL, NULL, &fds, pto);
		break;
	default:
		return -1;
	}

	if (sret < 0) {
		switch (errno) {
		case EINTR:
			// interrupt signal in select
			if (verbose >= 2)
				fprintf(stderr, "%s: EINTR\n", __func__);
			eagain = 1;
			break;
		case EAGAIN:
			if (verbose >= 2)
				fprintf(stderr, "%s: EAGAIN\n", __func__);
			break;
		default:
			if (verbose >= 2)
				fprintf(stderr, "%s: select failed: %s\n", __func__,
						strerror(errno));
			return -1;
		}
	} else if (sret == 0) {
		if (verbose >= 2)
			fprintf(stderr, "%s: timeout\n", __func__);
		return -ETIMEDOUT;
	}
} while (eagain);

return sret;

}

int socket_accept(int fd, uint16_t port)
{
#ifdef WIN32
int addr_len;
#else
socklen_t addr_len;
#endif
int result;
struct sockaddr_in addr;

memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr.sin_port = htons(port);

addr_len = sizeof(addr);
result = accept(fd, (struct sockaddr*)&addr, &addr_len);

return result;

}

int socket_shutdown(int fd, int how)
{
return shutdown(fd, how);
}

int socket_close(int fd) {
#ifdef WIN32
return closesocket(fd);
#else
return close(fd);
#endif
}

int socket_receive(int fd, void *data, size_t length)
{
return socket_receive_timeout(fd, data, length, 0, RECV_TIMEOUT);
}

int socket_peek(int fd, void *data, size_t length)
{
return socket_receive_timeout(fd, data, length, MSG_PEEK, RECV_TIMEOUT);
}

int socket_receive_timeout(int fd, void *data, size_t length, int flags,
unsigned int timeout)
{
int res;
int result;

// check if data is available
res = socket_check_fd(fd, FDM_READ, timeout);
if (res <= 0) {
	return res;
}
// if we get here, there _is_ data available
result = recv(fd, data, length, flags);
if (res > 0 && result == 0) {
	// but this is an error condition
	if (verbose >= 3)
		fprintf(stderr, "%s: fd=%d recv returned 0\n", __func__, fd);
	return -ECONNRESET;
}
if (result < 0) {
	return -errno;
}
return result;

}

int socket_send(int fd, void *data, size_t length)
{
int flags = 0;
#ifdef MSG_NOSIGNAL
flags |= MSG_NOSIGNAL;
#endif
return send(fd, data, length, flags);
}

from winlibimobiledevice.

vipinbeni avatar vipinbeni commented on August 17, 2024

Thanks a lot it working fine .

from winlibimobiledevice.

Related Issues (2)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.