-
-
Save felixSchl/1a8926689bc363e47a3b to your computer and use it in GitHub Desktop.
Force libnice to not use host candidates
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdlib.h> | |
#include <stdio.h> | |
#include <stdbool.h> | |
#include <string.h> | |
#include <ctype.h> | |
#include <unistd.h> | |
#include <agent.h> | |
#include <winsock2.h> | |
#define LOCAL_IP "192.168.1.60" | |
#define TAMPER_SDP | |
#if _WIN32 | |
bool wsa_init = false; | |
int inet_init(){ | |
if (wsa_init) | |
return 0; | |
WSADATA wsaData; | |
if (WSAStartup(MAKEWORD(2,2), &wsaData) == 0){ | |
wsa_init = true; | |
return 0; | |
} | |
return 1; | |
} | |
#endif | |
static GMainLoop *gloop; | |
static void* main_thread(void *data); | |
static void cb_candidate_gathering_done(NiceAgent *agent, guint stream_id, gpointer data); | |
static void cb_component_state_changed(NiceAgent *agent, guint stream_id, guint component_id, guint state, gpointer data); | |
static void cb_nice_recv(NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer data); | |
typedef struct Context { | |
gboolean is_controlling; | |
gboolean candidate_gathering_done; | |
GMutex gather_mutex; | |
GMutex connecting_mutex; | |
NiceAgent* agent; | |
GCond gather_cond; | |
char* name; | |
struct Context* other; | |
} Context; | |
Context* context_new( | |
GMainLoop* loop | |
, char* name | |
, gboolean is_controlling | |
) { | |
Context* context = malloc(sizeof(Context)); | |
g_cond_init(&context->gather_cond); | |
g_mutex_init(&context->gather_mutex); | |
g_mutex_init(&context->connecting_mutex); | |
context->candidate_gathering_done = FALSE; | |
context->is_controlling = is_controlling; | |
context->name = name; | |
context->agent = nice_agent_new( | |
g_main_loop_get_context(loop) | |
, NICE_COMPATIBILITY_RFC5245 | |
); | |
return context; | |
} | |
void context_set_other(Context* context, Context* other) { | |
context->other = other; | |
}; | |
int main (int argc, char *argv[]) { | |
GThread *thread_L; | |
GThread *thread_R; | |
#if _WIN32 | |
inet_init(); | |
#endif | |
nice_debug_enable(TRUE); | |
gloop = g_main_loop_new(NULL, FALSE); | |
Context* context_L = context_new(gloop, "L", TRUE); | |
Context* context_R = context_new(gloop, "R", FALSE); | |
context_set_other(context_L, context_R); | |
context_set_other(context_R, context_L); | |
thread_L = g_thread_new("thread (L)", &main_thread, context_L); | |
thread_R = g_thread_new("thread (R)", &main_thread, context_R); | |
g_main_loop_run(gloop); | |
g_thread_join(thread_L); | |
g_thread_join(thread_R); | |
g_main_loop_unref(gloop); | |
return EXIT_SUCCESS; | |
} | |
static void* main_thread(void* data) { | |
guint stream_id; | |
GMutex gather_mutex; | |
GCond gather_cond; | |
gchar *sdp, *sdp64; | |
NiceAddress* tmp_addr = NULL; | |
Context* context = data; | |
char* name = context->name; | |
fprintf( | |
stdout | |
, "%s: is controlling? - %s\n" | |
, name, (context->is_controlling) ? "YES" : "NO" | |
); | |
fflush(stdout); | |
// Set options ///////////////////////////////////////////////////////////// | |
fprintf(stdout, "%s: setting options...\n", name); | |
fflush(stdout); | |
g_object_set( | |
context->agent | |
, "ice-tcp", FALSE | |
, "stun-server", "52.5.57.211" | |
, "stun-server-port", 3478 | |
, "controlling-mode", context->is_controlling | |
, NULL | |
); | |
fprintf(stdout, "%s: options set!\n", name); | |
fflush(stdout); | |
// Set local address /////////////////////////////////////////////////////// | |
fprintf(stdout, "%s: setting local ip...\n", name); | |
fflush(stdout); | |
tmp_addr = nice_address_new(); | |
if (nice_address_set_from_string(tmp_addr, LOCAL_IP)) { | |
if(!nice_agent_add_local_address(context->agent, tmp_addr)) { | |
g_error("Failed to set local ip!"); | |
goto end; | |
} | |
} else { | |
int x = GetLastError(); | |
g_error("The local ip is invalid: `%s` (%d)", LOCAL_IP, x); | |
goto end; | |
} | |
fprintf(stdout, "%s: local ip set!\n", name); | |
fflush(stdout); | |
// Connect signals ///////////////////////////////////////////////////////// | |
fprintf(stdout, "%s: connecting signals...\n", name); | |
fflush(stdout); | |
g_signal_connect( | |
context->agent | |
, "candidate-gathering-done" | |
, G_CALLBACK(cb_candidate_gathering_done) | |
, context | |
); | |
g_signal_connect( | |
context->agent | |
, "component-state-changed" | |
, G_CALLBACK(cb_component_state_changed) | |
, context | |
); | |
fprintf(stdout, "%s: signals connected!\n", name); | |
fflush(stdout); | |
// Create streams ////////////////////////////////////////////////////////// | |
fprintf(stdout, "%s: creating stream...\n", name); | |
fflush(stdout); | |
stream_id = nice_agent_add_stream(context->agent, 1); | |
if (stream_id == 0) { | |
g_error("Failed to add stream", name); | |
goto end; | |
} | |
fprintf(stdout, "%s: stream created!\n", name); | |
fflush(stdout); | |
fprintf(stdout, "%s: setting stream name...\n", name); | |
fflush(stdout); | |
nice_agent_set_stream_name(context->agent, stream_id, "text"); | |
fprintf(stdout, "%s: stream name set!\n", name); | |
fflush(stdout); | |
// Attach receive callback ///////////////////////////////////////////////// | |
fprintf(stdout, "%s: attaching receive callback...\n", name); | |
fflush(stdout); | |
nice_agent_attach_recv( | |
context->agent | |
, stream_id | |
, 1 | |
, g_main_loop_get_context(gloop) | |
, cb_nice_recv | |
, context | |
); | |
fprintf(stdout, "%s: receive callback attached!\n", name); | |
fflush(stdout); | |
// Gather candidates /////////////////////////////////////////////////////// | |
fprintf(stdout, "%s: gathering candidates...\n", name); | |
fflush(stdout); | |
if (!nice_agent_gather_candidates(context->agent, stream_id)) { | |
g_error("Failed to start candidate gathering"); | |
goto end; | |
} | |
g_mutex_lock(&context->gather_mutex); | |
while (!context->candidate_gathering_done) { | |
g_cond_wait(&context->gather_cond, &context->gather_mutex); | |
} | |
g_mutex_unlock(&context->gather_mutex); | |
fprintf(stdout, "%s: candidate gathering done!\n", name); | |
fflush(stdout); | |
// Create SDP ////////////////////////////////////////////////////////////// | |
sdp = nice_agent_generate_local_sdp (context->agent); | |
fprintf(stdout, "%s: generated SDP from agent: \n%s\n", name, sdp); | |
fflush(stdout); | |
char tmp_sdp[4096] = ""; | |
#ifdef TAMPER_SDP | |
char line_buffer[1024] = ""; | |
int line_buffer_offset = 0; | |
int i = 0; | |
for (i = 0; i < strlen(sdp); i++) { | |
if (sdp[i] == '\n') { | |
if (!strstr(line_buffer, "typ host")) { | |
strcat(tmp_sdp, "\n"); | |
strcat(tmp_sdp, line_buffer); | |
} | |
strcpy(line_buffer, ""); | |
line_buffer_offset = 0; | |
} else { | |
line_buffer[line_buffer_offset] = sdp[i]; | |
line_buffer_offset += 1; | |
} | |
} | |
strcat(tmp_sdp, "\n"); | |
#else | |
strcpy(tmp_sdp, sdp); | |
#endif | |
fprintf(stdout, "%s: modified SDP from agent: \n%s\n", name, tmp_sdp); | |
fflush(stdout); | |
/* context->other->agent */ | |
nice_agent_parse_remote_sdp( | |
context->other->agent | |
, tmp_sdp | |
); | |
while (TRUE) { | |
usleep(100000); | |
} | |
end: | |
if (sdp) { | |
g_free(sdp); | |
} | |
g_object_unref(context->agent); | |
return NULL; | |
} | |
static void cb_candidate_gathering_done( | |
NiceAgent *agent | |
, guint stream_id | |
, gpointer data | |
) { | |
Context* context = data; | |
g_mutex_lock(&context->gather_mutex); | |
context->candidate_gathering_done = TRUE; | |
g_cond_signal(&context->gather_cond); | |
g_mutex_unlock(&context->gather_mutex); | |
} | |
static void cb_component_state_changed( | |
NiceAgent *agent | |
, guint stream_id | |
, guint component_id | |
, guint state | |
, gpointer data | |
) { | |
Context* context = data; | |
fprintf( | |
stdout | |
, "%s: state-change for stream %d / component %d: %s\n" | |
, context->name | |
, stream_id | |
, component_id | |
, nice_component_state_to_string(state) | |
); | |
fflush(stdout); | |
} | |
static void cb_nice_recv( | |
NiceAgent *agent | |
, guint stream_id | |
, guint component_id | |
, guint len | |
, gchar *buf | |
, gpointer data | |
) { | |
Context* context = data; | |
fprintf(stdout, "%s: Received data: %.*s\n", context->name, len, buf); | |
fflush(stdout); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment