From: Munkyu Im Date: Fri, 8 May 2015 13:23:33 +0000 (+0900) Subject: net: support bridged network X-Git-Tag: TizenStudio_2.0_p3.0~240 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=18df101589944cb85c8e65f0b276a36ce39f45b0;p=sdk%2Femulator%2Fqemu.git net: support bridged network Change-Id: Ia38c660d8ddf8b19325bf1817b96ad809f65714a Signed-off-by: Munkyu Im --- diff --git a/include/net/tap.h b/include/net/tap.h index 6daeb42..cf7021a 100644 --- a/include/net/tap.h +++ b/include/net/tap.h @@ -28,6 +28,9 @@ #include "qemu-common.h" #include "qapi-types.h" +#if defined(CONFIG_MARU) +#include "tizen/src/emul_state.h" +#endif int tap_enable(NetClientState *nc); int tap_disable(NetClientState *nc); diff --git a/net/tap-linux.c b/net/tap-linux.c index 812bf2d..f960781 100644 --- a/net/tap-linux.c +++ b/net/tap-linux.c @@ -36,6 +36,80 @@ #define PATH_NET_TUN "/dev/net/tun" +#if defined(CONFIG_MARU) +static int launch_openvpn(bool ismake, const char *ifname) +{ + int pid, status; + const char* args[] = { + "/usr/bin/sudo", + "/usr/sbin/openvpn", + "--mktun", + "--dev", + ifname, + NULL + }; + if (ismake) { + fprintf(stdout, "launch_openvpn make tap: %s\n", ifname); + } else { + fprintf(stdout, "launch_openvpn remove tap: %s\n", ifname); + args[2] = "--rmtun"; + } + /* try to launch network script */ + pid = fork(); + if (pid == 0) { + execv(args[0], (char**)args); + _exit(1); + } else if (pid > 0) { + while (waitpid(pid, &status, 0) != pid) { + /* loop */ + } + + if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { + return 0; + } + } + fprintf(stderr, "Could not launch openvpn\n"); + return -1; +} + +static int tap_cleanup(void) +{ + int fd, ret; + struct ifreq ifr; + char dname[100]; + int port = get_emul_vm_base_port() + 10; + + TFR(fd = open(PATH_NET_TUN, O_RDWR)); + if (fd < 0) { + error_report("could not open %s: %m", PATH_NET_TUN); + return -1; + } + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + + for ( ; port < 26200; port += 10) { + snprintf(dname, sizeof(dname), "tap%d", port); + pstrcpy(ifr.ifr_name, IFNAMSIZ, dname); + ret = ioctl(fd, TUNSETIFF, (void *) &ifr); + if (ret == 0) { + close(fd); + if (launch_openvpn(false, dname)) { + fprintf(stderr, "Failed to remove %s device. It can be used on the other emulator\n", dname); + } + TFR(fd = open(PATH_NET_TUN, O_RDWR)); + if (fd < 0) { + error_report("could not open %s: %m", PATH_NET_TUN); + return -1; + } + } else { + close(fd); + } + } + return 0; +} + +#endif + int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required, int mq_required) { @@ -43,7 +117,11 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int fd, ret; int len = sizeof(struct virtio_net_hdr); unsigned int features; - +#if defined(CONFIG_MARU) + if (tap_cleanup() < 0) { + return -1; + } +#endif TFR(fd = open(PATH_NET_TUN, O_RDWR)); if (fd < 0) { error_report("could not open %s: %m", PATH_NET_TUN); @@ -97,8 +175,20 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, if (ifname[0] != '\0') pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname); - else + else { +#if defined(CONFIG_MARU) + /* Create tap */ + char dname[100]; + snprintf(dname, sizeof dname, "tap%d", get_emul_vm_base_port()); + if (launch_openvpn(true, dname)) { + close(fd); + return -1; + } + pstrcpy(ifr.ifr_name, IFNAMSIZ, dname); +#else pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d"); +#endif + } ret = ioctl(fd, TUNSETIFF, (void *) &ifr); if (ret != 0) { if (ifname[0] != '\0') { diff --git a/tizen/src/emul_state.c b/tizen/src/emul_state.c index d56a519..b39efe9 100644 --- a/tizen/src/emul_state.c +++ b/tizen/src/emul_state.c @@ -189,6 +189,36 @@ char* get_emul_guest_ip(void) return _emul_info.guest_ip; } +void set_emul_host_ip(char *kernel_cmdline) +{ +#ifdef SUPPORT_LEGACY_ARGS + char *buf = strstr(kernel_cmdline, HOST_IP_PREFIX); +#else + char *buf = get_variable("host_ip"); +#endif + if (buf) { + char buf_host_ip[MAXLEN] = {0,}; + int len = strlen(HOST_IP_PREFIX); + int i, j; + int max_len = strlen(buf); + for(i = len, j = 0; i < max_len; i++) { + if (buf[i] == ' ' || buf[i] == '\0') + break; + buf_host_ip[j++] = buf[i]; + } + + buf_host_ip[j] = '\0'; + LOG_INFO("host_ip information=%s\n", buf_host_ip); + strncpy(_emul_info.host_ip, buf_host_ip, sizeof(_emul_info.host_ip)); + } +} + +char* get_emul_host_ip(void) +{ + LOG_INFO("host ip: %s\n", _emul_info.guest_ip); + return _emul_info.host_ip; +} + /* maximum number of touch point */ void set_emul_max_touch_point(int cnt) { @@ -387,6 +417,35 @@ char* get_emul_vm_name(void) return _emul_info.vm_name; } +/* emualtor http proxy */ +void set_emul_http_proxy_addr(char *addr) +{ + strncpy(_emul_info.http_proxy_addr, addr, sizeof(_emul_info.http_proxy_addr)); +} + +char* get_emul_http_proxy_addr(void) +{ + if (strlen(_emul_info.http_proxy_addr) > 0) { + return _emul_info.http_proxy_addr; + } else { + return NULL; + } +} + +void set_emul_http_proxy_port(char *port) +{ + strncpy(_emul_info.http_proxy_port, port, sizeof(_emul_info.http_proxy_port)); +} + +char* get_emul_http_proxy_port(void) +{ + if (strlen(_emul_info.http_proxy_port) > 0) { + return _emul_info.http_proxy_port; + } else { + return NULL; + } +} + void set_emul_hds_attached(bool attached) { _emul_state.hds_attached = attached; diff --git a/tizen/src/emul_state.h b/tizen/src/emul_state.h index b2146bc..56534ce 100644 --- a/tizen/src/emul_state.h +++ b/tizen/src/emul_state.h @@ -37,6 +37,8 @@ #include "display/maru_finger.h" #define SUPPORT_LEGACY_ARGS +#define MAX_ADDR_LEN 256 +#define MAX_PORT_LEN 256 #define MAX_HDS_PATH 256 #define MAX_PROFILE 256 @@ -97,8 +99,12 @@ typedef struct EmulatorConfigInfo { int vm_base_port; int device_serial_number; int ecs_port; + char http_proxy_addr[MAX_ADDR_LEN]; + char http_proxy_port[MAX_PORT_LEN]; + bool tap_enable; char guest_ip[16]; + char host_ip[16]; int spice_port; char *vm_name; @@ -147,6 +153,7 @@ void set_emul_max_touch_point(int cnt); void set_emul_vm_base_port(int port); void set_emul_ecs_port(int port); void set_emul_guest_ip(char *ip); +void set_emul_host_ip(char *ip); void set_emul_vm_name(char *vm_name); void set_emul_skin_path(char *path); void set_emul_gpu_accel(bool enable); @@ -159,6 +166,8 @@ void set_emul_rotation(short rotation_type); void set_emul_caps_lock_state(int state); void set_emul_num_lock_state(int state); void set_emul_tap_enable(bool enable); +void set_emul_http_proxy_addr(char *addr); +void set_emul_http_proxy_port(char *port); void set_emul_hds_attached(bool attached); void set_emul_hds_path(const char *path); void set_emul_hds_guest_path(const char *path); @@ -195,7 +204,10 @@ int get_host_lock_key_state_darwin(int key); int get_emul_caps_lock_state(void); int get_emul_num_lock_state(void); char* get_emul_guest_ip(void); +char* get_emul_host_ip(void); bool is_emul_tap_enable(void); +char* get_emul_http_proxy_addr(void); +char* get_emul_http_proxy_port(void); bool get_emul_hds_attached(void); char* get_emul_hds_path(void); diff --git a/tizen/src/emulator.c b/tizen/src/emulator.c index bd4ef2e..ad1b7d9 100644 --- a/tizen/src/emulator.c +++ b/tizen/src/emulator.c @@ -172,6 +172,43 @@ static void print_options_info(void) fprintf(stdout, "\n====================================================\n"); } +static void http_proxy_setup(gchar * const kernel_cmdline) +{ +#ifdef SUPPORT_LEGACY_ARGS + char *buf = strstr(kernel_cmdline, HTTP_PROXY_PREFIX); +#else + char *buf = get_variable("network_proxy"); +#endif + gchar** proxy; + if (buf) { + char http_proxy[MAXLEN] = {0,}; + int len = strlen(HTTP_PROXY_PREFIX); + int i, j; + int max_len = strlen(buf); + for(i = len, j = 0; i < max_len; i++) { + if (buf[i] == ' ') + break; + http_proxy[j++] = buf[i]; + } + + http_proxy[j] = '\0'; + proxy = g_strsplit(http_proxy, ":", -1); + if (g_strv_length(proxy) > 1) { + if (proxy[0] != NULL && proxy[1] != NULL) { + LOG_INFO("http_proxy information= addr: %s, port: %s\n", proxy[0], proxy[1]); + set_emul_http_proxy_addr(proxy[0]); + set_emul_http_proxy_port(proxy[1]); + } + } else { + LOG_INFO("http proxy is NULL\n"); + } + + if (proxy != NULL) { + g_strfreev(proxy); + } + } +} + #define PROXY_BUFFER_LEN 128 static void prepare_basic_features(gchar * const kernel_cmdline) { @@ -193,6 +230,8 @@ static void prepare_basic_features(gchar * const kernel_cmdline) " vm_resolution=%dx%d", get_emul_vm_base_port(), get_emul_resolution_width(), get_emul_resolution_height()); + http_proxy_setup(kernel_cmdline); + g_strlcat(kernel_cmdline, tmp_str, LEN_MARU_KERNEL_CMDLINE); g_free(tmp_str); diff --git a/tizen/src/emulator_common.h b/tizen/src/emulator_common.h index 99821be..34142b2 100644 --- a/tizen/src/emulator_common.h +++ b/tizen/src/emulator_common.h @@ -58,6 +58,10 @@ #endif #define JAVA_MAX_COMMAND_LENGTH 1024 +#define MAXLEN 512 +#define HTTP_PROXY_PREFIX "http_proxy=" +#define HOST_IP_PREFIX "host_ip=" + #define JAR_SKINFILE "emulator-skin.jar" #define JAVA_LIBRARY_PATH "-Djava.library.path" diff --git a/tizen/src/scripts/emulator-ifup-darwin.sh b/tizen/src/scripts/emulator-ifup-darwin.sh new file mode 100755 index 0000000..2a0ed71 --- /dev/null +++ b/tizen/src/scripts/emulator-ifup-darwin.sh @@ -0,0 +1,31 @@ +#!/bin/sh -x +BRIDGE=bridge1 +TAP=$1 +BASE=en0 + +#get base network information +IP=`ipconfig getifaddr $BASE` +NETMASK=`ifconfig $BASE | grep "inet " | awk '{print $4}'` +GW=`netstat -rn | grep ^default | awk '{print $2}'` + +#create bridge interface +CHECK_BR=`ifconfig | grep ^bridge1:` +if [ "$CHECK_BR" = "" ] +then + ifconfig $BRIDGE create +fi + +#add base network and tap device to bridge +ifconfig $BRIDGE addm $BASE +ifconfig $BRIDGE addm $TAP +ifconfig $BRIDGE up + +#set IP of base network to bridge +ifconfig $BASE delete $IP +ifconfig $BRIDGE $IP netmask $NETMASK + +#change network interface of default gateway +NET=`netstat -rn | grep ^default | awk '{print $6}'` +if [ $NET != $BRIDGE ];then +route change default $GW +fi diff --git a/tizen/src/scripts/emulator-ifup-linux.sh b/tizen/src/scripts/emulator-ifup-linux.sh new file mode 100755 index 0000000..3e059ff --- /dev/null +++ b/tizen/src/scripts/emulator-ifup-linux.sh @@ -0,0 +1,37 @@ +#!/bin/sh +x + +BASEIF=eth0 +NETMASK=`ifconfig $BASE | grep "inet " | awk '{print $4}' | cut -d : -f2` +GW=`netstat -rn | grep ^0.0.0.0 | awk '{print $2}'` +BR=br-tizen-vm-1 + +# Check if bridge interface exists. +CHECK_BR=`ifconfig $BR` +if [ "$CHECK_BR" = "" ] +then + BASEIPADDR=`ip addr show eth0 | awk '/inet / {print $2}' | cut -d/ -f1` + brctl addbr $BR +else + BASEIPADDR=`ip addr show $BR | awk '/inet / {print $2}' | cut -d/ -f1` +fi + +# ifconfig up tap device. +ifconfig $1 0.0.0.0 promisc up + +# Take interface down. +ifdown $BASEIF +ifconfig $BASEIF 0.0.0.0 promisc up + +# Add tap device and interface to bridge. +brctl addif $BR $BASEIF +brctl addif $BR $1 + +# Add the default route. +ifconfig $BR $BASEIPADDR netmask $NETMASK + +NET=`netstat -rn | grep ^0.0.0.0 | awk '{print $8}'` +if [ "$NET" != "$BR" ] +then + route add default gw $GW +fi +exit 0 diff --git a/tizen/src/skin/client/src/org/tizen/emulator/skin/EmulatorSkin.java b/tizen/src/skin/client/src/org/tizen/emulator/skin/EmulatorSkin.java index 31982a5..bc7c714 100644 --- a/tizen/src/skin/client/src/org/tizen/emulator/skin/EmulatorSkin.java +++ b/tizen/src/skin/client/src/org/tizen/emulator/skin/EmulatorSkin.java @@ -1934,21 +1934,46 @@ public class EmulatorSkin { } String emulName = SkinUtil.getVmName(config); - int portSdb = config.getArgInt(ArgsConstants.VM_BASE_PORT); + int basePort = config.getArgInt(ArgsConstants.VM_BASE_PORT); + String proxyAddr = config.getArg(ArgsConstants.PROXY_ADDR); + String proxyPort = config.getArg(ArgsConstants.PROXY_PORT); ProcessBuilder procEcp = new ProcessBuilder(); // FIXME: appropriate running binary setting is necessary. if (SwtUtil.isWindowsPlatform()) { - procEcp.command("java.exe", "-jar", ecpPath, "vmname=" - + emulName, "base.port=" + portSdb); + if (proxyAddr != null && proxyPort != null) { + procEcp.command("java.exe", "-Dhttp.proxyHost=" + + proxyAddr, "-Dhttp.proxyPort=" + proxyPort, + "-jar", ecpPath, "vmname=" + emulName, + "base.port=" + basePort); + } else { + procEcp.command("java.exe", "-jar", ecpPath, "vmname=" + + emulName, "base.port=" + basePort); + } } else if (SwtUtil.isMacPlatform()) { - procEcp.command("java", "-jar", "-XstartOnFirstThread", - ecpPath, "vmname=" + emulName, "base.port=" - + portSdb); + if (proxyAddr != null && proxyPort != null) { + procEcp.command("java", + "-Dhttp.proxyHost=" + proxyAddr, + "-Dhttp.proxyPort=" + proxyPort, "-jar", + "-XstartOnFirstThread", ecpPath, "vmname=" + + emulName, "base.port=" + basePort); + } else { + procEcp.command("java", "-jar", "-XstartOnFirstThread", + ecpPath, "vmname=" + emulName, "base.port=" + + basePort); + } } else { /* Linux */ - procEcp.command("java", "-jar", ecpPath, "vmname=" - + emulName, "base.port=" + portSdb); + if (proxyAddr != null && proxyPort != null) { + procEcp.command("java", + "-Dhttp.proxyHost=" + proxyAddr, + "-Dhttp.proxyPort=" + proxyPort, "-jar", + ecpPath, "vmname=" + emulName, "base.port=" + + basePort); + } else { + procEcp.command("java", "-jar", ecpPath, "vmname=" + + emulName, "base.port=" + basePort); + } } logger.info(procEcp.command().toString()); diff --git a/tizen/src/skin/client/src/org/tizen/emulator/skin/config/EmulatorConfig.java b/tizen/src/skin/client/src/org/tizen/emulator/skin/config/EmulatorConfig.java index 7e30c44..ddd2848 100644 --- a/tizen/src/skin/client/src/org/tizen/emulator/skin/config/EmulatorConfig.java +++ b/tizen/src/skin/client/src/org/tizen/emulator/skin/config/EmulatorConfig.java @@ -82,6 +82,8 @@ public class EmulatorConfig { public static final String INPUT_MOUSE = "input.mouse"; public static final String INPUT_TOUCHSCREEN = "input.touch"; public static final String INPUT_TOUCH_MAXPOINT = "input.touch.maxpoint"; + public static final String PROXY_ADDR = "proxy.addr"; + public static final String PROXY_PORT = "proxy.port"; } public interface SkinPropertiesConstants { diff --git a/tizen/src/skin/maruskin_client.c b/tizen/src/skin/maruskin_client.c index 589a287..953019a 100644 --- a/tizen/src/skin/maruskin_client.c +++ b/tizen/src/skin/maruskin_client.c @@ -66,6 +66,8 @@ MULTI_DEBUG_CHANNEL(qemu, skinclient); #define OPT_INPUT_MOUSE "input.mouse" #define OPT_INPUT_TOUCH "input.touch" #define OPT_MAX_TOUCHPOINT "input.touch.maxpoint" +#define OPT_PROXY_ADDR "proxy.addr" +#define OPT_PROXY_PORT "proxy.port" #define OPT_BOOLEAN_TRUE "true" #define OPT_BOOLEAN_FALSE "false" @@ -103,9 +105,9 @@ static void *run_skin_client(void *arg) int skin_server_port = get_skin_server_port(); int vm_base_port = get_emul_vm_base_port(); - char buf_skin_server_port[16]; - char buf_uid[16]; - char buf_vm_base_port[16]; + char buf_skin_server_port[16] = { 0, }; + char buf_uid[16] = { 0, }; + char buf_vm_base_port[16] = { 0, }; sprintf(buf_skin_server_port, "%d", skin_server_port); sprintf(buf_uid, "%d", uid); sprintf(buf_vm_base_port, "%d", vm_base_port); @@ -126,10 +128,26 @@ static void *run_skin_client(void *arg) /* input */ char buf_input[12] = { 0, }; - if (is_emul_input_mouse_enable() == true) + if (is_emul_input_mouse_enable() == true) { strcpy(buf_input, OPT_INPUT_MOUSE); - else + } else { strcpy(buf_input, OPT_INPUT_TOUCH); + } + + /* network */ + gchar const* proxy_addr; + int proxy_addr_len = 0; + + if (get_emul_http_proxy_addr() == NULL) { + proxy_addr = g_strdup_printf("%s= %s=", + OPT_PROXY_ADDR, OPT_PROXY_PORT); + proxy_addr_len = (int)strlen(proxy_addr); + } else { + proxy_addr = g_strdup_printf("%s=%s %s=%s", + OPT_PROXY_ADDR, get_emul_http_proxy_addr(), + OPT_PROXY_PORT, get_emul_http_proxy_port()); + proxy_addr_len = (int)strlen(proxy_addr); + } #ifdef CONFIG_WIN32 /* find java path in 64bit windows */ @@ -187,7 +205,8 @@ static void *run_skin_client(void *arg) strlen(buf_input) + EQUAL_LEN + strlen(OPT_BOOLEAN_TRUE) + SPACE_LEN + strlen(OPT_MAX_TOUCHPOINT) + EQUAL_LEN + - len_maxtouchpoint + SPACE_LEN + 1 + + len_maxtouchpoint + SPACE_LEN + + proxy_addr_len + SPACE_LEN + 1 + strlen(argv); INFO("skin command length : %d\n", cmd_len); @@ -207,6 +226,7 @@ static void *run_skin_client(void *arg) %s=%s \ %s=%s \ %s=%d \ +%s \ %s", JAVA_EXEFILE_PATH, JAVA_EXEOPTION, JAVA_LIBRARY_PATH, #ifdef CONFIG_WIN32 @@ -221,6 +241,7 @@ static void *run_skin_client(void *arg) OPT_DISPLAY_SHM, buf_display_shm, buf_input, OPT_BOOLEAN_TRUE, OPT_MAX_TOUCHPOINT, maxtouchpoint, + proxy_addr, argv); INFO("command for swt : %s\n", cmd); diff --git a/tizen/src/ui/menu/contextmenu.cpp b/tizen/src/ui/menu/contextmenu.cpp index 1dc5f7e..efc25da 100644 --- a/tizen/src/ui/menu/contextmenu.cpp +++ b/tizen/src/ui/menu/contextmenu.cpp @@ -673,6 +673,17 @@ void ContextMenu::slotControlPanel() /* SWT Display must be created on main thread due to Cocoa restrictions */ arguments << "-XstartOnFirstThread"; #endif + QString httpProxyAddr; + QString httpProxyPort; + if (get_emul_http_proxy_addr()) { + httpProxyAddr = "-Dhttp.proxyHost=" + QString(get_emul_http_proxy_addr()); + httpProxyPort = "-Dhttp.proxyPort=" + QString(get_emul_http_proxy_port()); + } + + if (httpProxyAddr != NULL && httpProxyPort != NULL) { + arguments << httpProxyAddr << httpProxyPort; + } + arguments << "-jar" << ecpPath << vmNameOpt << basePortOpt; qDebug() << command << arguments;