/*
- * Copyright (c) 2015-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2015-2017, 2020 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
@interface AgentController()
@property (nonatomic) NSMutableDictionary * floatingProxyAgentList;
+@property (nonatomic) NSMutableDictionary * floatingProxyAgentList_TCPConverter;
@property (nonatomic) NSMutableDictionary * floatingDNSAgentList;
@property (nonatomic) NSMutableDictionary * policyDB;
@property (nonatomic) NEPolicySession * policySession;
}
}
+ if (self.floatingProxyAgentList_TCPConverter == nil) {
+ self.floatingProxyAgentList_TCPConverter = [NSMutableDictionary dictionary];
+ if (self.floatingProxyAgentList_TCPConverter == nil) {
+ errorMessage = "Failed to create a dictionary";
+ break;
+ }
+ }
+
/* A dictionary of all floating dns agents
* Key : <entity-name> (can be an interface name or domain name)
* Value : agent object
/* Make sure that we have all our data structures in place */
return ((self.policySession != nil) &&
(self.floatingProxyAgentList != nil) &&
+ (self.floatingProxyAgentList_TCPConverter != nil) &&
(self.floatingDNSAgentList != nil) &&
(self.policyDB != nil) &&
(self.controllerQueue != nil));
- (int)countProxyEntriesEnabled:(CFDictionaryRef)proxies
{
- int enabled = 0;
+ const CFStringRef enableKeys[] = {
+ kSCPropNetProxiesHTTPEnable,
+ kSCPropNetProxiesHTTPSEnable,
+ kSCPropNetProxiesProxyAutoConfigEnable,
+ kSCPropNetProxiesFTPEnable,
+ kSCPropNetProxiesGopherEnable,
+ kSCPropNetProxiesRTSPEnable,
+ kSCPropNetProxiesSOCKSEnable,
+ kSCPropNetProxiesTransportConverterEnable,
+ kSCPropNetProxiesProxyAutoDiscoveryEnable,
+ };
if (proxies == NULL) {
- SC_log(LOG_NOTICE, "Invalid proxies");
+ SC_log(LOG_NOTICE, "No proxies");
return 0;
}
- if (([self getIntValue:CFDictionaryGetValue(proxies, kSCPropNetProxiesHTTPEnable) valuePtr:&enabled] && enabled > 0) ||
- ([self getIntValue:CFDictionaryGetValue(proxies, kSCPropNetProxiesHTTPSEnable) valuePtr:&enabled] && enabled > 0) ||
- ([self getIntValue:CFDictionaryGetValue(proxies, kSCPropNetProxiesProxyAutoConfigEnable) valuePtr:&enabled] && enabled > 0) ||
- ([self getIntValue:CFDictionaryGetValue(proxies, kSCPropNetProxiesFTPEnable) valuePtr:&enabled] && enabled > 0) ||
- ([self getIntValue:CFDictionaryGetValue(proxies, kSCPropNetProxiesGopherEnable) valuePtr:&enabled] && enabled > 0) ||
- ([self getIntValue:CFDictionaryGetValue(proxies, kSCPropNetProxiesRTSPEnable) valuePtr:&enabled] && enabled > 0) ||
- ([self getIntValue:CFDictionaryGetValue(proxies, kSCPropNetProxiesSOCKSEnable) valuePtr:&enabled] && enabled > 0) ||
- ([self getIntValue:CFDictionaryGetValue(proxies, kSCPropNetProxiesProxyAutoDiscoveryEnable) valuePtr:&enabled] && enabled > 0)) {
- return enabled;
+ for (size_t i = 0; i < (sizeof(enableKeys) / sizeof(enableKeys[0])); i++) {
+ int enabled = 0;
+
+ if ([self getIntValue:CFDictionaryGetValue(proxies, enableKeys[i])
+ valuePtr:&enabled] &&
+ (enabled > 0)) {
+ return enabled;
+ }
}
return 0;
return NO;
}
+- (BOOL)isTCPConverterProxyEnabled:(CFDictionaryRef)proxies
+{
+ int enabled = 0;
+ CFNumberRef num = NULL;
+
+ if (CFDictionaryGetValueIfPresent(proxies,
+ kSCPropNetProxiesTransportConverterEnable,
+ (const void **)&num) &&
+ isA_CFNumber(num) &&
+ CFNumberGetValue(num, kCFNumberIntType, &enabled) &&
+ (enabled != 0)) {
+ return YES;
+ }
+
+ return NO;
+}
+
+#define ALLOW_AGGREGATE "net.inet.mptcp.allow_aggregate"
+
+static void
+updateTransportConverterProxyEnabled(BOOL enabled)
+{
+ int ret;
+ int val = enabled ? 1 : 0;
+
+ ret = sysctlbyname(ALLOW_AGGREGATE, NULL, 0, &val, sizeof(val));
+ if (ret != -1) {
+ SC_log(LOG_NOTICE, "Transport Converter Proxy: sysctl " ALLOW_AGGREGATE "=%d", val);
+ } else {
+ if (errno != ENOENT) {
+ SC_log(LOG_ERR, "sysctlbyname(" ALLOW_AGGREGATE ") failed: %s", strerror(errno));
+ }
+ }
+
+ return;
+}
+
- (void)processDefaultProxyChanges:(CFDictionaryRef)proxies
{
CFArrayRef global_proxy;
}
if (spawnAgent) {
+ BOOL ok;
+
AgentSubType subtype = kAgentSubTypeDefault;
NEPolicyConditionType conditionType = NEPolicyConditionTypeNone;
if ([self isGlobalProxy:proxies_copy]) {
subtype = kAgentSubTypeGlobal;
}
- [self spawnFloatingAgent:[ProxyAgent class]
- entity:@proxyAgentDefault
- agentSubType:subtype
- addPolicyOfType:conditionType
- publishData:data];
+ ok = [self spawnFloatingAgent:[ProxyAgent class]
+ entity:@proxyAgentDefault
+ agentSubType:subtype
+ addPolicyOfType:conditionType
+ publishData:data];
+ if (ok &&
+ (subtype == kAgentSubTypeGlobal) &&
+ [self isTCPConverterProxyEnabled:proxies_copy]) {
+ proxyAgent = [self.floatingProxyAgentList objectForKey:@proxyAgentDefault];
+ if ((proxyAgent != nil) &&
+ [data isEqual:[proxyAgent getAgentData]]) {
+ [self.floatingProxyAgentList_TCPConverter setObject:proxyAgent
+ forKey:@proxyAgentDefault];
+ updateTransportConverterProxyEnabled(TRUE); // enable "net.inet.mptcp.allow_aggregate"
+ }
+ }
}
} else {
/* No default proxy config OR generic (no protocols enabled) default proxy config.
BOOL ok = NO;
if ( agent != nil) {
+ NSString * entity = [agent getAssociatedEntity];
NSMutableArray * policyArray;
policyArray = [self.policyDB objectForKey:[agent getAgentName]];
[self.policyDB removeObjectForKey:[agent getAgentName]];
}
+ SC_log(LOG_INFO, "Destroying floating agent for %@", entity);
+
if ([agent getAgentType] == kAgentTypeProxy) {
- [self.floatingProxyAgentList removeObjectForKey:[agent getAssociatedEntity]];
+ [self.floatingProxyAgentList removeObjectForKey:entity];
+
+ [self.floatingProxyAgentList_TCPConverter removeObjectForKey:entity];
+ if ([self.floatingProxyAgentList_TCPConverter count] == 0) {
+ updateTransportConverterProxyEnabled(FALSE); // disable "net.inet.mptcp.allow_aggregate"
+ }
} else {
[self.floatingDNSAgentList removeObjectForKey:[agent getAssociatedEntity]];
}
[self unregisterAgent:agent];
}
- SC_log(LOG_INFO, "X - Destroyed agent %@", [agent getAgentName]);
-
/* Check if we need to close the "control" policy session */
if (self.controlPolicySession != nil) {
NSMutableArray *globalProxyAgentList;
self.controlPolicySession = nil;
SC_log(LOG_NOTICE, "Closed control policy session");
+
}
}
CFStringRef key2;
CFStringRef key3;
} pick_list[] = {
- { kSCPropNetProxiesFTPEnable, kSCPropNetProxiesFTPProxy, kSCPropNetProxiesFTPPort },
- { kSCPropNetProxiesGopherEnable, kSCPropNetProxiesGopherProxy, kSCPropNetProxiesGopherPort },
- { kSCPropNetProxiesHTTPEnable, kSCPropNetProxiesHTTPProxy, kSCPropNetProxiesHTTPPort },
- { kSCPropNetProxiesHTTPSEnable, kSCPropNetProxiesHTTPSProxy, kSCPropNetProxiesHTTPSPort },
- { kSCPropNetProxiesRTSPEnable, kSCPropNetProxiesRTSPProxy, kSCPropNetProxiesRTSPPort },
- { kSCPropNetProxiesSOCKSEnable, kSCPropNetProxiesSOCKSProxy, kSCPropNetProxiesSOCKSPort },
+ { kSCPropNetProxiesFTPEnable,
+ kSCPropNetProxiesFTPProxy,
+ kSCPropNetProxiesFTPPort
+ },
+ { kSCPropNetProxiesGopherEnable,
+ kSCPropNetProxiesGopherProxy,
+ kSCPropNetProxiesGopherPort
+ },
+ { kSCPropNetProxiesHTTPEnable,
+ kSCPropNetProxiesHTTPProxy,
+ kSCPropNetProxiesHTTPPort
+ },
+ { kSCPropNetProxiesHTTPSEnable,
+ kSCPropNetProxiesHTTPSProxy,
+ kSCPropNetProxiesHTTPSPort
+ },
+ { kSCPropNetProxiesRTSPEnable,
+ kSCPropNetProxiesRTSPProxy,
+ kSCPropNetProxiesRTSPPort
+ },
+ { kSCPropNetProxiesSOCKSEnable,
+ kSCPropNetProxiesSOCKSProxy,
+ kSCPropNetProxiesSOCKSPort
+ },
+ { kSCPropNetProxiesTransportConverterEnable,
+ kSCPropNetProxiesTransportConverterProxy,
+ kSCPropNetProxiesTransportConverterPort
+ },
{ kSCPropNetProxiesProxyAutoConfigEnable,
kSCPropNetProxiesProxyAutoConfigURLString,
- kSCPropNetProxiesProxyAutoConfigJavaScript, },
+ kSCPropNetProxiesProxyAutoConfigJavaScript
+ },
{ kSCPropNetProxiesProxyAutoDiscoveryEnable,
NULL,
- NULL, }
+ NULL
+ }
};
if ((state_dict == NULL) && (setup_dict == NULL)) {
/*
- * Copyright (c) 2004-2007, 2009, 2010-2013, 2015-2020 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2007, 2009, 2010-2013, 2015-2021 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
SC_log(level, " Service %2ld : %@, %2d (%@%s%@%s%@)",
orderIndex + 1,
serviceID,
- __SCNetworkInterfaceOrder(SCNetworkServiceGetInterface(service)), // temp?
+ __SCNetworkInterfaceOrder(interface), // temp?
serviceName,
bsdName != NULL ? ", " : "",
bsdName != NULL ? bsdName : CFSTR(""),
} else {
SC_log(level, " Service : %@, %2d (%@%s%@%s%@)",
serviceID,
- __SCNetworkInterfaceOrder(SCNetworkServiceGetInterface(service)), // temp?
+ __SCNetworkInterfaceOrder(interface), // temp?
serviceName,
bsdName != NULL ? ", " : "",
bsdName != NULL ? bsdName : CFSTR(""),
/*
- * Copyright (c) 2004-2020 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2021 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)interface;
int order;
+ if (isA_SCNetworkInterface(interface) == NULL) {
+ // arbitrarily large number
+ return INT_MAX;
+ }
order = interfacePrivate->sort_order << 1;
if (!interfacePrivate->builtin) {
order |= 0x1; // push non-builtin after built-in
/*
- * Copyright (c) 2004-2020 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2021 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
setPrivate->setID);
continue; // if the service is not a link
}
-
+ if (SCPreferencesPathGetValue(setPrivate->prefs, link) == NULL) {
+ SC_log(LOG_INFO, "service \"%@\" for set \"%@\" broken link \"%@\"",
+ keys[i],
+ setPrivate->setID,
+ link);
+ continue; // the link is broken
+ }
components = CFStringCreateArrayBySeparatingStrings(NULL, link, CFSTR("/"));
if (CFArrayGetCount(components) == 3) {
CFStringRef serviceID;
/*
- * Copyright (c) 2000, 2001, 2003-2005, 2007-2009, 2011, 2014-2020 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003-2005, 2007-2009, 2011, 2014-2021 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
Boolean isDefault = FALSE;
SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs;
+ if (prefs == NULL) {
+ // if no prefs, assume that we are using the "default" prefs
+ return TRUE;
+ }
+
curPath = prefsPrivate->newPath ? prefsPrivate->newPath : prefsPrivate->path;
if (curPath != NULL) {
char* defPath;
static void
validate_proxy_content(CFMutableDictionaryRef proxies,
- CFStringRef proxy_enable,
- CFStringRef proxy_host,
- CFStringRef proxy_port,
- const char * proxy_service,
- int proxy_defaultport)
+ CFStringRef proxy_enable_key,
+ CFStringRef proxy_host_key,
+ CFStringRef proxy_port_key,
+ const char * proxy_service_name,
+ int proxy_defaultport,
+ Boolean multiple_proxies)
{
int enabled = 0;
CFNumberRef num;
- num = CFDictionaryGetValue(proxies, proxy_enable);
+ num = CFDictionaryGetValue(proxies, proxy_enable_key);
if (num != NULL) {
if (!isA_CFNumber(num) ||
!CFNumberGetValue(num, kCFNumberIntType, &enabled)) {
}
}
- if (proxy_host != NULL) {
- CFStringRef host;
+ if (proxy_host_key != NULL) {
+ CFTypeRef host_val;
- host = CFDictionaryGetValue(proxies, proxy_host);
- if ((enabled == 0) && (host != NULL)) {
+ host_val = CFDictionaryGetValue(proxies, proxy_host_key);
+ if ((enabled == 0) && (host_val != NULL)) {
goto disable; // if not enabled, remove provided key/value
}
- if ((enabled != 0) &&
- (!isA_CFString(host) || (CFStringGetLength(host) == 0))) {
- goto disable; // if enabled, not provided (or not valid)
+ if (enabled != 0) {
+ if (isA_CFString(host_val)) {
+ CFStringRef host = (CFStringRef)host_val;
+
+ if (multiple_proxies) {
+ goto disable; // if multiple proxies expected
+ }
+
+ if (CFStringGetLength(host) == 0) {
+ goto disable; // if proxy host string not valid
+ }
+ } else if (isA_CFArray(host_val)) {
+ CFArrayRef hosts = (CFArrayRef)host_val;
+ CFIndex n;
+
+ if (!multiple_proxies) {
+ goto disable; // if single proxy expected
+ }
+
+ n = CFArrayGetCount(hosts);
+ if (n == 0) {
+ goto disable; // if no hosts provided
+ }
+
+ for (CFIndex i = 0; i < n; i++) {
+ CFStringRef host = CFArrayGetValueAtIndex(hosts, i);
+
+ if (!isA_CFString(host) || (CFStringGetLength(host) == 0)) {
+ goto disable; // if proxy host string not valid
+ }
+ }
+ } else {
+ goto disable; // not valid
+ }
}
}
- if (proxy_port != NULL) {
+ if (proxy_port_key != NULL) {
CFNumberRef port;
int s_port = 0;
- port = CFDictionaryGetValue(proxies, proxy_port);
+ port = CFDictionaryGetValue(proxies, proxy_port_key);
if ((enabled == 0) && (port != NULL)) {
goto disable; // if not enabled, remove provided key/value
}
if ((enabled != 0) && (port == NULL)) {
struct servent *service;
- service = getservbyname(proxy_service, "tcp");
+ if (proxy_service_name == NULL) {
+ goto disable; // no "default" port available
+ }
+
+ service = getservbyname(proxy_service_name, "tcp");
if (service != NULL) {
s_port = ntohs(service->s_port);
} else {
s_port = proxy_defaultport;
}
num = CFNumberCreate(NULL, kCFNumberIntType, &s_port);
- CFDictionarySetValue(proxies, proxy_port, num);
+ CFDictionarySetValue(proxies, proxy_port_key, num);
CFRelease(num);
}
}
enabled = 0;
num = CFNumberCreate(NULL, kCFNumberIntType, &enabled);
- CFDictionarySetValue(proxies, proxy_enable, num);
+ CFDictionarySetValue(proxies, proxy_enable_key, num);
CFRelease(num);
- if (proxy_host != NULL) {
- CFDictionaryRemoveValue(proxies, proxy_host);
+ if (proxy_host_key != NULL) {
+ CFDictionaryRemoveValue(proxies, proxy_host_key);
}
- if (proxy_port != NULL) {
- CFDictionaryRemoveValue(proxies, proxy_port);
+ if (proxy_port_key != NULL) {
+ CFDictionaryRemoveValue(proxies, proxy_port_key);
}
return;
kSCPropNetProxiesFTPProxy,
kSCPropNetProxiesFTPPort,
"ftp",
- 21);
+ 21,
+ FALSE);
validate_proxy_content(newProxy,
kSCPropNetProxiesGopherEnable,
kSCPropNetProxiesGopherProxy,
kSCPropNetProxiesGopherPort,
"gopher",
- 70);
+ 70,
+ FALSE);
validate_proxy_content(newProxy,
kSCPropNetProxiesHTTPEnable,
kSCPropNetProxiesHTTPProxy,
kSCPropNetProxiesHTTPPort,
"http",
- 80);
+ 80,
+ FALSE);
validate_proxy_content(newProxy,
kSCPropNetProxiesHTTPSEnable,
kSCPropNetProxiesHTTPSProxy,
kSCPropNetProxiesHTTPSPort,
"https",
- 443);
+ 443,
+ FALSE);
validate_proxy_content(newProxy,
kSCPropNetProxiesRTSPEnable,
kSCPropNetProxiesRTSPProxy,
kSCPropNetProxiesRTSPPort,
"rtsp",
- 554);
+ 554,
+ FALSE);
validate_proxy_content(newProxy,
kSCPropNetProxiesSOCKSEnable,
kSCPropNetProxiesSOCKSProxy,
kSCPropNetProxiesSOCKSPort,
"socks",
- 1080);
+ 1080,
+ FALSE);
+ validate_proxy_content(newProxy,
+ kSCPropNetProxiesTransportConverterEnable,
+ kSCPropNetProxiesTransportConverterProxy,
+ kSCPropNetProxiesTransportConverterPort,
+ NULL,
+ 0,
+ TRUE);
if (CFDictionaryContainsKey(newProxy, kSCPropNetProxiesProxyAutoConfigURLString)) {
validate_proxy_content(newProxy,
kSCPropNetProxiesProxyAutoConfigEnable,
kSCPropNetProxiesProxyAutoConfigURLString,
NULL,
NULL,
- 0);
+ 0,
+ FALSE);
// and we can't have both URLString and JavaScript keys
CFDictionaryRemoveValue(newProxy, kSCPropNetProxiesProxyAutoConfigJavaScript);
kSCPropNetProxiesProxyAutoConfigJavaScript,
NULL,
NULL,
- 0);
+ 0,
+ FALSE);
}
validate_proxy_content(newProxy,
kSCPropNetProxiesProxyAutoDiscoveryEnable,
NULL,
NULL,
NULL,
- 0);
+ 0,
+ FALSE);
validate_proxy_content(newProxy,
kSCPropNetProxiesFallBackAllowed,
NULL,
NULL,
NULL,
- 0);
+ 0,
+ FALSE);
// validate FTP passive setting
num = CFDictionaryGetValue(newProxy, kSCPropNetProxiesFTPPassive);
const CFStringRef kSCPropNetProxiesProxyAutoConfigJavaScript = CFSTR("ProxyAutoConfigJavaScript");
const CFStringRef kSCPropNetProxiesProxyAutoConfigURLString = CFSTR("ProxyAutoConfigURLString");
const CFStringRef kSCPropNetProxiesProxyAutoDiscoveryEnable = CFSTR("ProxyAutoDiscoveryEnable");
+const CFStringRef kSCPropNetProxiesTransportConverterEnable = CFSTR("TransportConverterEnable");
+const CFStringRef kSCPropNetProxiesTransportConverterPort = CFSTR("TransportConverterPort");
+const CFStringRef kSCPropNetProxiesTransportConverterProxy = CFSTR("TransportConverterProxy");
+const CFStringRef kSCPropNetProxiesTransportConverterFallBackAllowed = CFSTR("TransportConverterFallBackAllowed");
+const CFStringRef kSCPropNetProxiesTransportConverterMultipathServiceType = CFSTR("TransportConverterMultipathServiceType");
+const CFStringRef kSCPropNetProxiesTransportConverterTFOMode = CFSTR("TransportConverterTFOMode");
const CFStringRef kSCPropNetProxiesBypassAllowed = CFSTR("BypassAllowed");
const CFStringRef kSCPropNetProxiesFallBackAllowed = CFSTR("FallBackAllowed");
const CFStringRef kSCPropNetProxiesSupplementalMatchDomains = CFSTR("SupplementalMatchDomains");
*
* kSCEntNetProxies Entity Keys
*
+ * kSCPropNetProxiesTransportConverterEnable "TransportConverterEnable" CFNumber (0 or 1)
+ * kSCPropNetProxiesTransportConverterPort "TransportConverterPort" CFNumber
+ * kSCPropNetProxiesTransportConverterProxy "TransportConverterProxy" CFArray[CFString]
+ * kSCPropNetProxiesTransportConverterFallBackAllowed "TransportConverterFallBackAllowed" CFNumber (0 or 1)
+ * kSCPropNetProxiesTransportConverterMultipathServiceType "TransportConverterMultipathServiceType" CFNumber
+ * kSCPropNetProxiesTransportConverterTFOMode "TransportConverterTFOMode" CFNumber
+ *
* kSCPropNetProxiesBypassAllowed "BypassAllowed" CFNumber (0 or 1)
* kSCPropNetProxiesFallBackAllowed "FallBackAllowed" CFNumber (0 or 1)
* kSCPropNetProxiesSupplementalMatchDomains "SupplementalMatchDomains" CFArray[CFString]
@const kSCEntNetCaptivePortal
@discussion Value is a CFDictionary
*/
-extern const CFStringRef kSCEntNetCaptivePortal SPI_AVAILABLE(macos(10.16), ios(14.0), tvos(14.0), watchos(7.0), bridgeos(5.0));
+extern const CFStringRef kSCEntNetCaptivePortal SPI_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0), watchos(7.0), bridgeos(5.0));
#define kSCEntNetCaptivePortal kSCEntNetCaptivePortal
/*!
@const kSCPropNetCaptivePortalURL
@discussion Value is a CFString
*/
-extern const CFStringRef kSCPropNetCaptivePortalURL SPI_AVAILABLE(macos(10.16), ios(14.0), tvos(14.0), watchos(7.0), bridgeos(5.0));
+extern const CFStringRef kSCPropNetCaptivePortalURL SPI_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0), watchos(7.0), bridgeos(5.0));
#define kSCPropNetCaptivePortalURL kSCPropNetCaptivePortalURL
/*!
@group kSCEntNetProxies Entity Keys
*/
+/*!
+ @const kSCPropNetProxiesTransportConverterEnable
+ @discussion Value is a CFNumber (0 or 1)
+ */
+extern const CFStringRef kSCPropNetProxiesTransportConverterEnable API_AVAILABLE(macos(11.0)) SPI_AVAILABLE(ios(14.0), tvos(14.0), watchos(7.0), bridgeos(5.0));
+#define kSCPropNetProxiesTransportConverterEnable kSCPropNetProxiesTransportConverterEnable
+
+/*!
+ @const kSCPropNetProxiesTransportConverterPort
+ @discussion Value is a CFNumber
+ */
+extern const CFStringRef kSCPropNetProxiesTransportConverterPort API_AVAILABLE(macos(11.0)) SPI_AVAILABLE(ios(14.0), tvos(14.0), watchos(7.0), bridgeos(5.0));
+#define kSCPropNetProxiesTransportConverterPort kSCPropNetProxiesTransportConverterPort
+
+/*!
+ @const kSCPropNetProxiesTransportConverterProxy
+ @discussion Value is a CFArray[CFString]
+ */
+extern const CFStringRef kSCPropNetProxiesTransportConverterProxy API_AVAILABLE(macos(11.0)) SPI_AVAILABLE(ios(14.0), tvos(14.0), watchos(7.0), bridgeos(5.0));
+#define kSCPropNetProxiesTransportConverterProxy kSCPropNetProxiesTransportConverterProxy
+
+/*!
+ @const kSCPropNetProxiesTransportConverterFallBackAllowed
+ @discussion Value is a CFNumber (0 or 1)
+ */
+extern const CFStringRef kSCPropNetProxiesTransportConverterFallBackAllowed API_AVAILABLE(macos(11.0)) SPI_AVAILABLE(ios(14.0), tvos(14.0), watchos(7.0), bridgeos(5.0));
+#define kSCPropNetProxiesTransportConverterFallBackAllowed kSCPropNetProxiesTransportConverterFallBackAllowed
+
+/*!
+ @const kSCPropNetProxiesTransportConverterMultipathServiceType
+ @discussion Value is a CFNumber
+ */
+extern const CFStringRef kSCPropNetProxiesTransportConverterMultipathServiceType API_AVAILABLE(macos(11.0)) SPI_AVAILABLE(ios(14.0), tvos(14.0), watchos(7.0), bridgeos(5.0));
+#define kSCPropNetProxiesTransportConverterMultipathServiceType kSCPropNetProxiesTransportConverterMultipathServiceType
+
+/*!
+ @const kSCPropNetProxiesTransportConverterTFOMode
+ @discussion Value is a CFNumber
+ */
+extern const CFStringRef kSCPropNetProxiesTransportConverterTFOMode API_AVAILABLE(macos(11.0)) SPI_AVAILABLE(ios(14.0), tvos(14.0), watchos(7.0), bridgeos(5.0));
+#define kSCPropNetProxiesTransportConverterTFOMode kSCPropNetProxiesTransportConverterTFOMode
+
/*!
@const kSCPropNetProxiesBypassAllowed
@discussion Value is a CFNumber (0 or 1)
SC_10_14_IPHONE_12_0_PRIVATE,
SC_10_15_IPHONE_13_0_PRIVATE,
SC_10_15_4_IPHONE_13_4_PRIVATE,
+ SC_11_0_IPHONE_14_0_PRIVATE,
SC_IPHONE_2_0_PRIVATE,
SC_IPHONE_7_0_PRIVATE,
SC_IPHONE_8_0_PRIVATE,
#define MSCHAP1 "MSCHAP1"
#define MSCHAP2 "MSCHAP2"
#define MTU "MTU"
+#define MULTIPATH "Multipath"
#define NAME "Name"
#define NAT64 "NAT64"
#define NETBIOS "NetBIOS"
#define TAG "Tag"
#define TAGS "Tags"
#define TERMINALSCRIPT "TerminalScript"
+#define TFO "TFO"
#define TIMEOUT "Timeout"
#define TIMER "Timer"
#define TIMESTAMP "TimeStamp"
#define TOKEN "Token"
#define TRANSMITACCM "TransmitACCM"
#define TRANSPORT "Transport"
+#define TRANSPORTCONVERTER "TransportConverter"
#define TSO "TSO"
#define TSO4 "TSO4"
#define TSO6 "TSO6"
{ GROUP_PRIVATE, NETPROP PROXIES, KEY_PREFIX NETENT PROXIES " Entity Keys", NULL, NULL },
+ { SC_11_0_IPHONE_14_0_PRIVATE, NETPROP PROXIES, TRANSPORTCONVERTER ENABLE, NULL, CFNUMBER_BOOL },
+ { SC_11_0_IPHONE_14_0_PRIVATE, NETPROP PROXIES, TRANSPORTCONVERTER PORT, NULL, CFNUMBER },
+ { SC_11_0_IPHONE_14_0_PRIVATE, NETPROP PROXIES, TRANSPORTCONVERTER PROXY, NULL, CFARRAY_CFSTRING },
+ { SC_11_0_IPHONE_14_0_PRIVATE, NETPROP PROXIES, TRANSPORTCONVERTER FALLBACK ALLOWED, NULL, CFNUMBER_BOOL },
+ { SC_11_0_IPHONE_14_0_PRIVATE, NETPROP PROXIES, TRANSPORTCONVERTER MULTIPATH SERVICE TYPE, NULL, CFNUMBER },
+ { SC_11_0_IPHONE_14_0_PRIVATE, NETPROP PROXIES, TRANSPORTCONVERTER TFO MODE, NULL, CFNUMBER },
+ { COMMENT_PRIVATE, "", NULL, NULL, NULL },
{ SC_10_9_IPHONE_7_0_PRIVATE, NETPROP PROXIES, BYPASS ALLOWED, NULL, CFNUMBER_BOOL },
{ SC_10_9_IPHONE_6_0_PRIVATE, NETPROP PROXIES, FALLBACK ALLOWED, NULL, CFNUMBER_BOOL },
{ SC_10_7_IPHONE_5_0_PRIVATE, NETPROP PROXIES, SUPPLEMENTAL MATCH DOMAINS, NULL, CFARRAY_CFSTRING},
case SC_10_15_4_IPHONE_13_4_PRIVATE:
printf(" API_AVAILABLE(macos(10.15.4)) SPI_AVAILABLE(ios(13.4), tvos(13.4), watchos(6.2), bridgeos(4.0));\n");
break;
+ case SC_11_0_IPHONE_14_0_PRIVATE:
+ printf(" API_AVAILABLE(macos(11.0)) SPI_AVAILABLE(ios(14.0), tvos(14.0), watchos(7.0), bridgeos(5.0));\n");
+ break;
case SC_IPHONE_2_0_PRIVATE:
printf(" SPI_AVAILABLE(macos(10.6), ios(2.0), tvos(9.0), watchos(1.0), bridgeos(1.0));\n");
break;
printf(" SPI_AVAILABLE(macos(10.0), ios(8.0), tvos(9.0), watchos(1.0), bridgeos(1.0));\n");
break;
case SC_IPHONE_14_PRIVATE:
- printf(" SPI_AVAILABLE(macos(10.16), ios(14.0), tvos(14.0), watchos(7.0), bridgeos(5.0));\n");
+ printf(" SPI_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0), watchos(7.0), bridgeos(5.0));\n");
break;
default:
printf("\n");
case SC_10_14_IPHONE_12_0_PRIVATE:
case SC_10_15_IPHONE_13_0_PRIVATE:
case SC_10_15_4_IPHONE_13_4_PRIVATE:
+ case SC_11_0_IPHONE_14_0_PRIVATE:
case SC_IPHONE_2_0_PRIVATE:
case SC_IPHONE_7_0_PRIVATE:
case SC_IPHONE_8_0_PRIVATE:
case SC_10_14_IPHONE_12_0_PRIVATE:
case SC_10_15_IPHONE_13_0_PRIVATE:
case SC_10_15_4_IPHONE_13_4_PRIVATE:
+ case SC_11_0_IPHONE_14_0_PRIVATE:
case SC_IPHONE_2_0_PRIVATE:
case SC_IPHONE_7_0_PRIVATE:
case SC_IPHONE_8_0_PRIVATE:
case SC_10_14_IPHONE_12_0_PRIVATE:
case SC_10_15_IPHONE_13_0_PRIVATE:
case SC_10_15_4_IPHONE_13_4_PRIVATE:
+ case SC_11_0_IPHONE_14_0_PRIVATE:
case SC_IPHONE_2_0_PRIVATE:
case SC_IPHONE_7_0_PRIVATE:
case SC_IPHONE_8_0_PRIVATE:
case SC_10_14_IPHONE_12_0_PRIVATE:
case SC_10_15_IPHONE_13_0_PRIVATE:
case SC_10_15_4_IPHONE_13_4_PRIVATE:
+ case SC_11_0_IPHONE_14_0_PRIVATE:
case SC_IPHONE_2_0_PRIVATE:
case SC_IPHONE_7_0_PRIVATE:
case SC_IPHONE_8_0_PRIVATE:
const CFStringRef *keyProxy;
const CFStringRef *keyPort;
const CFStringRef *keyURL;
+ const Boolean multiple_proxies;
} proxyKeys;
-static proxyKeys proxyKeys_FTP = { "FTP" , &kSCPropNetProxiesFTPEnable , &kSCPropNetProxiesFTPProxy , &kSCPropNetProxiesFTPPort , NULL };
-static proxyKeys proxyKeys_Gopher = { "Gopher", &kSCPropNetProxiesGopherEnable , &kSCPropNetProxiesGopherProxy, &kSCPropNetProxiesGopherPort, NULL };
-static proxyKeys proxyKeys_HTTP = { "HTTP" , &kSCPropNetProxiesHTTPEnable , &kSCPropNetProxiesHTTPProxy , &kSCPropNetProxiesHTTPPort , NULL };
-static proxyKeys proxyKeys_HTTPS = { "HTTPS" , &kSCPropNetProxiesHTTPSEnable , &kSCPropNetProxiesHTTPSProxy , &kSCPropNetProxiesHTTPSPort , NULL };
-static proxyKeys proxyKeys_RTSP = { "RTSP" , &kSCPropNetProxiesRTSPEnable , &kSCPropNetProxiesRTSPProxy , &kSCPropNetProxiesRTSPPort , NULL };
-static proxyKeys proxyKeys_SOCKS = { "SOCKS" , &kSCPropNetProxiesSOCKSEnable , &kSCPropNetProxiesSOCKSProxy , &kSCPropNetProxiesSOCKSPort , NULL };
-static proxyKeys proxyKeys_PAC = { ".pac" , &kSCPropNetProxiesProxyAutoConfigEnable , NULL , NULL , &kSCPropNetProxiesProxyAutoConfigURLString };
-static proxyKeys proxyKeys_WPAD = { "WPAD" , &kSCPropNetProxiesProxyAutoDiscoveryEnable, NULL , NULL , NULL };
+static proxyKeys proxyKeys_FTP = { "FTP",
+ &kSCPropNetProxiesFTPEnable,
+ &kSCPropNetProxiesFTPProxy,
+ &kSCPropNetProxiesFTPPort,
+ NULL,
+ FALSE
+ };
+static proxyKeys proxyKeys_Gopher = { "Gopher",
+ &kSCPropNetProxiesGopherEnable,
+ &kSCPropNetProxiesGopherProxy,
+ &kSCPropNetProxiesGopherPort,
+ NULL,
+ FALSE
+ };
+static proxyKeys proxyKeys_HTTP = { "HTTP",
+ &kSCPropNetProxiesHTTPEnable,
+ &kSCPropNetProxiesHTTPProxy,
+ &kSCPropNetProxiesHTTPPort,
+ NULL,
+ FALSE
+ };
+static proxyKeys proxyKeys_HTTPS = { "HTTPS",
+ &kSCPropNetProxiesHTTPSEnable,
+ &kSCPropNetProxiesHTTPSProxy,
+ &kSCPropNetProxiesHTTPSPort,
+ NULL,
+ FALSE
+ };
+static proxyKeys proxyKeys_RTSP = { "RTSP",
+ &kSCPropNetProxiesRTSPEnable,
+ &kSCPropNetProxiesRTSPProxy,
+ &kSCPropNetProxiesRTSPPort,
+ NULL,
+ FALSE
+ };
+static proxyKeys proxyKeys_SOCKS = { "SOCKS",
+ &kSCPropNetProxiesSOCKSEnable,
+ &kSCPropNetProxiesSOCKSProxy,
+ &kSCPropNetProxiesSOCKSPort,
+ NULL,
+ FALSE
+ };
+static proxyKeys proxyKeys_TransportConverter =
+ { "TransportConverter",
+ &kSCPropNetProxiesTransportConverterEnable,
+ &kSCPropNetProxiesTransportConverterProxy,
+ &kSCPropNetProxiesTransportConverterPort,
+ NULL,
+ TRUE
+ };
+static proxyKeys proxyKeys_PAC = { ".pac",
+ &kSCPropNetProxiesProxyAutoConfigEnable,
+ NULL,
+ NULL,
+ &kSCPropNetProxiesProxyAutoConfigURLString,
+ FALSE};
+static proxyKeys proxyKeys_WPAD = { "WPAD",
+ &kSCPropNetProxiesProxyAutoDiscoveryEnable,
+ NULL,
+ NULL,
+ NULL,
+ FALSE};
static proxyKeys *currentProxy = NULL;
{ "HTTPS" , NULL , isOther , NULL , __doProxySelect , (void *)&proxyKeys_HTTPS },
{ "RTSP" , NULL , isOther , NULL , __doProxySelect , (void *)&proxyKeys_RTSP },
{ "SOCKS" , NULL , isOther , NULL , __doProxySelect , (void *)&proxyKeys_SOCKS },
+ { "TransportConverter" , NULL , isOther , NULL , __doProxySelect , (void *)&proxyKeys_TransportConverter },
{ "ProxyAutoConfig" , NULL , isOther , NULL , __doProxySelect , (void *)&proxyKeys_PAC },
{ ".pac" , NULL , isOther , NULL , __doProxySelect , (void *)&proxyKeys_PAC },
{ "ProxyAutoDiscovery" , NULL , isOther , NULL , __doProxySelect , (void *)&proxyKeys_WPAD },
{ "enable" , NULL , isOther , NULL , __doProxyEnable , (void *)TRUE },
{ "proxy" , NULL , isOther , NULL , __doProxyHost , NULL },
{ "host" , NULL , isOther , NULL , __doProxyHost , NULL },
+ { "proxies" , NULL , isOther , NULL , __doProxyHost , NULL },
+ { "hosts" , NULL , isOther , NULL , __doProxyHost , NULL },
{ "port" , NULL , isOther , NULL , __doProxyPort , NULL },
{ "url" , NULL , isOther , NULL , __doProxyURL , NULL },
// (ftp) proxy modifiers
" set protocol socks host proxy-host\n"
" set protocol socks port proxy-port\n"
"\n"
+ " set protocol transportconverter {enable|disable}\n"
+ " set protocol transportconverter host[s] proxy-host[,proxy-host-2]\n"
+ " set protocol transportconverter port proxy-port\n"
+ "\n"
" set protocol .pac {enable|disable}\n"
" set protocol .pac url .pac-url\n"
"\n"
}
if (strlen(argv[0]) > 0) {
- CFStringRef host;
+ if (!currentProxy->multiple_proxies) {
+ CFStringRef host;
- host = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
- CFDictionarySetValue(newConfiguration, *(currentProxy->keyProxy), host);
- CFRelease(host);
+ host = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
+ CFDictionarySetValue(newConfiguration, *(currentProxy->keyProxy), host);
+ CFRelease(host);
+ } else {
+ CFArrayRef hosts;
+ CFStringRef hosts_str;
+
+ hosts_str = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
+ hosts = CFStringCreateArrayBySeparatingStrings(NULL, hosts_str, CFSTR(","));
+ CFDictionarySetValue(newConfiguration, *(currentProxy->keyProxy), hosts);
+ CFRelease(hosts);
+ CFRelease(hosts_str);
+ }
} else {
CFDictionaryRemoveValue(newConfiguration, *(currentProxy->keyProxy));
}