Example #1
0
int
start_plugin(const char *plugin,
             const char *plugin_opts,
             const char *remote_host,
             const char *remote_port,
             const char *local_host,
             const char *local_port,
#ifdef __MINGW32__
             uint16_t control_port,
#endif
             enum plugin_mode mode)
{
#ifndef __MINGW32__
    char *new_path = NULL;
    const char *current_path;
    size_t new_path_len;
#endif
    int ret;

    if (plugin == NULL)
        return -1;

    if (strlen(plugin) == 0)
        return 0;

#ifndef __MINGW32__
    /*
     * Add current dir to PATH, so we can search plugin in current dir
     */
    env          = cork_env_clone_current();
    current_path = cork_env_get(env, "PATH");
    if (current_path != NULL) {
#ifdef HAVE_GET_CURRENT_DIR_NAME
        char *cwd = get_current_dir_name();
        if (cwd) {
#else
        char cwd[PATH_MAX];
        if (!getcwd(cwd, PATH_MAX)) {
#endif
            new_path_len = strlen(current_path) + strlen(cwd) + 2;
            new_path     = ss_malloc(new_path_len);
            snprintf(new_path, new_path_len, "%s:%s", cwd, current_path);
#ifdef HAVE_GET_CURRENT_DIR_NAME
            free(cwd);
#endif
        }
    }
    if (new_path != NULL)
        cork_env_add(env, "PATH", new_path);
#else
    sub_control_port = control_port;
#endif

    if (!strncmp(plugin, "obfsproxy", strlen("obfsproxy")))
        ret = start_obfsproxy(plugin, plugin_opts, remote_host, remote_port,
                              local_host, local_port, mode);
    else
        ret = start_ss_plugin(plugin, plugin_opts, remote_host, remote_port,
                              local_host, local_port, mode);
#ifndef __MINGW32__
    ss_free(new_path);
#endif
    env = NULL;
    return ret;
}

uint16_t
get_local_port()
{
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0) {
        return 0;
    }

    struct sockaddr_in serv_addr;
    bzero((char *)&serv_addr, sizeof(serv_addr));
    serv_addr.sin_family      = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port        = 0;
    if (bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
        return 0;
    }

    socklen_t len = sizeof(serv_addr);
    if (getsockname(sock, (struct sockaddr *)&serv_addr, &len) == -1) {
        return 0;
    }
    if (close(sock) < 0) {
        return 0;
    }

    return ntohs(serv_addr.sin_port);
}

void
stop_plugin()
{
    if (sub != NULL) {
        cork_subprocess_abort(sub);
        cork_subprocess_free(sub);
    }
}

int
is_plugin_running()
{
    if (sub != NULL) {
        return cork_subprocess_is_finished(sub);
    }
    return 0;
}
Example #2
0
int
start_plugin(const char *plugin,
             const char *plugin_opts,
             const char *remote_host,
             const char *remote_port,
             const char *local_host,
             const char *local_port)
{
    char *new_path = NULL;
    char *cmd      = NULL;

    if (plugin == NULL)
        return -1;

    if (strlen(plugin) == 0)
        return 0;

    size_t plugin_len = strlen(plugin);
    size_t cmd_len = plugin_len + CMD_RESRV_LEN;
    cmd = ss_malloc(cmd_len);

    snprintf(cmd, cmd_len, "exec %s", plugin);

    env = cork_env_clone_current();
    const char *path = cork_env_get(env, "PATH");
    if (path != NULL) {
#ifdef __GLIBC__
        char *cwd = get_current_dir_name();
        if (cwd) {
#else
        char cwd[PATH_MAX];
        if (!getcwd(cwd, PATH_MAX)) {
#endif
            size_t path_len = strlen(path) + strlen(cwd) + 2;
            new_path = ss_malloc(path_len);
            snprintf(new_path, path_len, "%s:%s", cwd, path);
#ifdef __GLIBC__
            free(cwd);
#endif
        }
    }

    if (new_path != NULL)
        cork_env_add(env, "PATH", new_path);

    cork_env_add(env, "SS_REMOTE_HOST", remote_host);
    cork_env_add(env, "SS_REMOTE_PORT", remote_port);

    cork_env_add(env, "SS_LOCAL_HOST", local_host);
    cork_env_add(env, "SS_LOCAL_PORT", local_port);

    if (plugin_opts != NULL)
        cork_env_add(env, "SS_PLUGIN_OPTIONS", plugin_opts);

    exec = cork_exec_new_with_params("sh", "-c", cmd, NULL);

    cork_exec_set_env(exec, env);

    sub = cork_subprocess_new_exec(exec, NULL, NULL, &exit_code);

    int err = cork_subprocess_start(sub);

    ss_free(cmd);

    if (new_path != NULL)
        ss_free(new_path);

    return err;
}

uint16_t
get_local_port()
{
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0) {
        return 0;
    }

    struct sockaddr_in serv_addr;
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = 0;
    if (bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
        return 0;
    }

    socklen_t len = sizeof(serv_addr);
    if (getsockname(sock, (struct sockaddr *)&serv_addr, &len) == -1) {
        return 0;
    }
    if (close (sock) < 0) {
        return 0;
    }

    return ntohs(serv_addr.sin_port);
}

void
stop_plugin()
{
    if (sub != NULL) {
        cork_subprocess_abort(sub);
        cork_subprocess_free(sub);
    }
}

int is_plugin_running()
{
    if (sub != NULL) {
        return cork_subprocess_is_finished(sub);
    }
    return 0;
}