Accumulative patch from commit d5b559b6418c2bd09663e0d09e93a6592357fdce

d5b559b WNM: Add disassociation timeout processing for ESS_DISASSOC
f65f539 GAS: Reduce query timeout to two seconds
7a56af5 GAS: Assign new dialog token even if previous one is free
9e1ecab GAS: Ignore replays if previous frag_id without dropping GAS session
fa7ae95 Add test code for fetching the last configured GTK
576bce9 P2P: Direct global ctrl_iface commands automatically for P2P
c4bf83a P2P: No duplicate AP-STA-CONNECTED/DISCONNECTED as global event
7793c95 Clean up AP-STA-CONNECTED/DISCONNECTED prints
92c4465 P2P: Mark P2P events global (not specific to interface)
ed496f1 P2P: Clean up debug prints
710ae9a P2P: Move p2p_find stopped event message into p2p_supplicant.c
47bfe49 Add wpa_msg_global() for global events
214e428 Allow global ctrl_iface monitors
89c7ac5 wpa_cli: Set buffer length the same as in wpa_supplicant_ctrl_iface_process()
faf9a85 Add band option (2.4 vs. 5) for filtering scans
b83b1b2 Android: Clarify keystore include directories
6f1127c Android: Add a top level Android.mk
d2a9e2c Abstract and Android sockets for global ctrl_iface
6fd5cea wpa_cli: Allow global interface to be used in interactive mode
2925756 wpa_supplicant: Add -G argument to specify global ctrl group
cf3bebf Allow global ctrl_iface to be used for per-interface commands
058c863 FT RRB: Fix a memory leak on error path

Change-Id: I32a4afb43894167a30c4b0df18fd4846a2945c7c
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/common/wpa_ctrl.c b/src/common/wpa_ctrl.c
index 58cbe6a..d9a7509 100644
--- a/src/common/wpa_ctrl.c
+++ b/src/common/wpa_ctrl.c
@@ -82,6 +82,9 @@
 	int tries = 0;
 	int flags;
 
+	if (ctrl_path == NULL)
+		return NULL;
+
 	ctrl = os_malloc(sizeof(*ctrl));
 	if (ctrl == NULL)
 		return NULL;
@@ -126,13 +129,27 @@
 #ifdef ANDROID
 	chmod(ctrl->local.sun_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
 	chown(ctrl->local.sun_path, AID_SYSTEM, AID_WIFI);
+
+	if (os_strncmp(ctrl_path, "@android:", 9) == 0) {
+		if (socket_local_client_connect(
+			    ctrl->s, ctrl_path + 9,
+			    ANDROID_SOCKET_NAMESPACE_RESERVED,
+			    SOCK_DGRAM) < 0) {
+			close(ctrl->s);
+			unlink(ctrl->local.sun_path);
+			os_free(ctrl);
+			return NULL;
+		}
+		return ctrl;
+	}
+
 	/*
 	 * If the ctrl_path isn't an absolute pathname, assume that
 	 * it's the name of a socket in the Android reserved namespace.
 	 * Otherwise, it's a normal UNIX domain socket appearing in the
 	 * filesystem.
 	 */
-	if (ctrl_path != NULL && *ctrl_path != '/') {
+	if (*ctrl_path != '/') {
 		char buf[21];
 		os_snprintf(buf, sizeof(buf), "wpa_%s", ctrl_path);
 		if (socket_local_client_connect(
@@ -149,12 +166,18 @@
 #endif /* ANDROID */
 
 	ctrl->dest.sun_family = AF_UNIX;
-	res = os_strlcpy(ctrl->dest.sun_path, ctrl_path,
-			 sizeof(ctrl->dest.sun_path));
-	if (res >= sizeof(ctrl->dest.sun_path)) {
-		close(ctrl->s);
-		os_free(ctrl);
-		return NULL;
+	if (os_strncmp(ctrl_path, "@abstract:", 10) == 0) {
+		ctrl->dest.sun_path[0] = '\0';
+		os_strlcpy(ctrl->dest.sun_path + 1, ctrl_path + 10,
+			   sizeof(ctrl->dest.sun_path) - 1);
+	} else {
+		res = os_strlcpy(ctrl->dest.sun_path, ctrl_path,
+				 sizeof(ctrl->dest.sun_path));
+		if (res >= sizeof(ctrl->dest.sun_path)) {
+			close(ctrl->s);
+			os_free(ctrl);
+			return NULL;
+		}
 	}
 	if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
 		    sizeof(ctrl->dest)) < 0) {