Ejemplo n.º 1
0
static gboolean initialize_device(struct upnp_device_descriptor *device_def,
				  struct upnp_device *result_device,
				  const char *ip_address,
				  unsigned short port)
{
	int rc;
	char *buf;

	rc = UpnpInit(ip_address, port);
	if (UPNP_E_SUCCESS != rc) {
		Log_error("upnp", "UpnpInit(ip=%s, port=%d) Error: %s (%d)",
			  ip_address, port, UpnpGetErrorMessage(rc), rc);
		return FALSE;
	}
	Log_info("upnp", "Registered IP=%s port=%d\n",
		 UpnpGetServerIpAddress(), UpnpGetServerPort());

	rc = UpnpEnableWebserver(TRUE);
	if (UPNP_E_SUCCESS != rc) {
		Log_error("upnp", "UpnpEnableWebServer() Error: %s (%d)",
			  UpnpGetErrorMessage(rc), rc);
		return FALSE;
	}

	if (!webserver_register_callbacks())
	  return FALSE;

	rc = UpnpAddVirtualDir("/upnp");
	if (UPNP_E_SUCCESS != rc) {
		Log_error("upnp", "UpnpAddVirtualDir() Error: %s (%d)",
			  UpnpGetErrorMessage(rc), rc);
		return FALSE;
	}

       	buf = upnp_create_device_desc(device_def);
	rc = UpnpRegisterRootDevice2(UPNPREG_BUF_DESC,
				     buf, strlen(buf), 1,
				     &event_handler, result_device,
				     &(result_device->device_handle));
	free(buf);

	if (UPNP_E_SUCCESS != rc) {
		Log_error("upnp", "UpnpRegisterRootDevice2() Error: %s (%d)",
			  UpnpGetErrorMessage(rc), rc);
		return FALSE;
	}

	rc = UpnpSendAdvertisement(result_device->device_handle, 100);
	if (UPNP_E_SUCCESS != rc) {
		Log_error("unpp", "Error sending advertisements: %s (%d)",
			  UpnpGetErrorMessage(rc), rc);
		return FALSE;
	}

	return TRUE;
}
Ejemplo n.º 2
0
static int output_ffmpeg_stop(void) {
    Log_error("ffmpeg", "output_ffmpeg_stop ");
    if (s_pthread_id)
    {
        s_Exit_Flag = TRUE;
        if (get_current_player_state() == FFMPEG_STATE_PAUSED)
        {
            wakeup_pause_status();
        }
        pthread_join(s_pthread_id,NULL); 
        s_Exit_Flag = FALSE;
        Log_error("ffmpeg", "output_ffmpeg_stop 2");
        s_pthread_id = NULL;
    }
	return 0;
}
Ejemplo n.º 3
0
static int get(struct RandomSeed* rs, uint64_t buffer[8])
{
    struct RandomSeed_pvt* ctx = Identity_check((struct RandomSeed_pvt*) rs);
    Log_info(ctx->logger, "Attempting to seed random number generator");

    // each provider overwrites input and output is a rolling hash.
    struct RandomSeed_Buffer buff = { .output = {0} };

    int successCount = 0;
    for (int i = 0; i < ctx->rsCount; i++) {
        if (!ctx->rsList[i]->get(ctx->rsList[i], buff.input)) {
            Log_info(ctx->logger, "Trying random seed [%s] Success", ctx->rsList[i]->name);
            crypto_hash_sha512((uint8_t*)buff.output,
                               (uint8_t*)&buff,
                               RandomSeed_Buffer_SIZE);
            successCount++;
        } else {
            Log_info(ctx->logger, "Trying random seed [%s] Failed", ctx->rsList[i]->name);
        }
    }
    Assert_true(sizeof(buff.output) == 64);
    Bits_memcpy(buffer, buff.output, 64);

    if (successCount > 0) {
        Log_info(ctx->logger, "Seeding random number generator succeeded with [%d] sources",
                 successCount);
        return 0;
    } else {
        Log_error(ctx->logger, "Seeding random number generator failed");
        return -1;
    }
}
Ejemplo n.º 4
0
/*
 * Exported function implementations
 */
kern_return_t Task_createWithTask(Task* self, task_t task) {
	kern_return_t retVal = KERN_INVALID_ARGUMENT;
	if (self == NULL || task == TASK_NULL) {
		Log_invalidArgument("self: %p, task: %p", self, (void*) task);
		
	} else {
		pid_t pid = -1;
		(void) pid_for_task(task, &pid);	

		cpu_type_t cpuType = getCPUTypeForTask(pid);
		if (cpuType == CPU_TYPE_ARM) {
			printf("ARM; NOT IMPLEMENTED\n");
			//self->arch = TaskArch_ARM_create();
			
		} else if (cpuType == CPU_TYPE_I386 || cpuType == CPU_TYPE_X86) {
			self->arch = TaskArch_x86_create();
			
		} else if (cpuType == CPU_TYPE_X86_64) {
			self->arch = TaskArch_x86_64_create();
			
		} else {
			Log_error("Unsupported process architecture, %d", cpuType);
			retVal = KERN_FAILURE;
		}
		
		if (self->arch) {
			self->task = task;
			self->pid = pid;
			self->cpuType = cpuType;
			self->wordSize = getWordSize(pid);
			retVal = KERN_SUCCESS;
		}
	}
	return retVal;
}
Ejemplo n.º 5
0
static int output_ffmpeg_play(output_transition_cb_t callback) {
	Log_error("ffmpeg", "--play-- \n\n");

	int ret = 0;
	play_trans_callback_ = callback;

	
    
	if (s_pthread_id)
	{
        //如果,己经开启了,说明是正在暂停!
        if (get_current_player_state() == FFMPEG_STATE_PAUSED)
        {
            wakeup_pause_status();
            return 0;
        }
	}
    s_Exit_Flag = FALSE;
    // 创建线程
    ret = pthread_create(&s_pthread_id,NULL,(void  *) run_function,NULL);  
    if(ret!=0)  
    {  
        printf("Create pthread error!\n");  
        return ;  
    }  
	return 0;
}
Ejemplo n.º 6
0
static int output_ffmpeg_init(void)
{

	Log_error("ffmpeg", "output_ffmpeg_init----- ");

	SongMetaData_init(&song_meta_);
	register_mime_type("audio/*");
	register_mime_type("audio/x-mpeg");
	register_mime_type("audio/mpeg");
    av_register_all();
    avformat_network_init();

	//:(s_pFormatCtx = avformat_alloc_context();
    s_au_convert_ctx = swr_alloc();
    s_out_buffer = (uint8_t *)av_malloc(MAX_AUDIO_FRAME_SIZE * 2);
    s_pFrame = av_frame_alloc();

    mp_msg_init();
    char ** ao_list= malloc(sizeof(char*)*2);
    const int c_number_count = 10;
    *ao_list = malloc(sizeof(char) * c_number_count);
    ao_list[1] = malloc(sizeof(char) *c_number_count);
    strcpy(ao_list[0],"alsa");
    memset(ao_list[1],0, c_number_count);
    s_audio_device = init_best_audio_out(ao_list, 0, 44100, 2,AF_FORMAT_S16_LE,0);
    assert(s_audio_device != NULL);
    free(ao_list[0]);
    free(ao_list[1]);
    free(ao_list);
	
    mixer_Init_control_point(&s_mixer, s_audio_device);
	pthread_mutex_init(&s_mutex, NULL);
    pthread_cond_init(&s_cond, NULL);
	return 0;
}
Ejemplo n.º 7
0
static int output_ffmpeg_get_mute(int *m) {
	gboolean val=TRUE;
    Log_error("ffmpeg", "Set mute to %s", m ? "on" : "off");
    
	*m = val;
	return 0;
}
Ejemplo n.º 8
0
static int output_ffmpeg_get_volume(float *v) {
	float volume = 0.0f;
    mixer_getbothvolume(&s_mixer, &volume);
	Log_error("ffmpeg", "Query volume fraction: %f", volume);
	*v = volume;
	return 0;
}
Ejemplo n.º 9
0
gboolean webserver_register_callbacks(void) {
  int rc = UpnpSetVirtualDirCallbacks(&virtual_dir_callbacks);
  if (UPNP_E_SUCCESS != rc) {
    Log_error("webserver", "UpnpSetVirtualDirCallbacks() Error: %s (%d)",
	      UpnpGetErrorMessage(rc), rc);
    return FALSE;
  }
  return TRUE;
}
Ejemplo n.º 10
0
static int output_ffmpeg_seek(gint64 position_nanos) {
	Log_error("ffmpeg", "seek = %lld ", position_nanos);
	pthread_mutex_lock(&s_mutex);
	s_Seek_Flag = TRUE;
	s_want_to_seek_position = position_nanos;
	pthread_mutex_unlock(&s_mutex);
	
	
    return 0;
}
Ejemplo n.º 11
0
int output_init(const char *shortname)
{
	int count;

	count = sizeof(modules) / sizeof(struct output_module *);
	if (count == 0) {
		Log_error("output", "No output module available");
		return -1;
	}
	if (shortname == NULL) {
		output_module = modules[0];
	} else {
		int i;
		for (i=0; i<count; i++) {
			if (strcmp(modules[i]->shortname, shortname)==0) {
				output_module = modules[i];
				break;
			}
		}
	}
	
	if (output_module == NULL) {
		Log_error("error", "ERROR: No such output module: '%s'",
			  shortname);
		return -1;
	}

	Log_info("output", "Using output module: %s (%s)",
		 output_module->shortname, output_module->description);

	output_module->shared_metadata = shared_metadata_create();

	pthread_t thread;
	pthread_create(&thread, NULL, thread_update_track_time, NULL);


	if (output_module->init) {
		return output_module->init();
	}

	return 0;
}
Ejemplo n.º 12
0
static int output_ffmpeg_deinit(void)
{
    av_frame_free(&s_pFrame);
    swr_free(&s_au_convert_ctx);
    av_free(s_out_buffer);
    
    Log_error("ffmpeg", "output_ffmpeg_deinit 1");
    pthread_mutex_destroy(&s_mutex);
    Log_error("ffmpeg", "output_ffmpeg_deinit 2");
    
    if (s_pthread_id)
	{
		pthread_join(s_pthread_id,NULL); 
		Log_error("ffmpeg", "output_ffmpeg_deinit 3");
		s_pthread_id = NULL;
	}
	
	
    return 0;
}
Ejemplo n.º 13
0
// only in parent
static void inFromChild(evutil_socket_t socket, short eventType, void* vcontext)
{
    struct Admin* admin = (struct Admin*) vcontext;

    uint8_t buffer[MAX_API_REQUEST_SIZE];
    ssize_t amount = read(admin->inFd, buffer, MAX_API_REQUEST_SIZE);

    if (amount < 1) {
        if (amount == 0 || errno != EAGAIN) {
            if (amount < 0) {
                Log_error1(admin->logger, "Broken pipe to admin process, errno=%d", errno);
            } else {
                Log_error(admin->logger, "Connection to admin process closed unexpectedly");
            }
            event_free(admin->pipeEv);
        }
        return;
    }

    if (!admin->initialized) {
        if (amount != sizeof(struct sockaddr_storage) + sizeof(int) + 8) {
            Log_error(admin->logger, "unexpected length");
        } else if (memcmp(buffer, "abcd", 4)) {
            Log_error(admin->logger, "bad magic");
        } else if (memcmp(&buffer[sizeof(struct sockaddr_storage) + sizeof(int) + 4], "wxyz", 4)) {
            Log_error(admin->logger, "bad magic");
        } else {
            Bits_memcpyConst(&admin->addressLength, &buffer[4], sizeof(int));
            Bits_memcpyConst(&admin->address,
                             &buffer[4 + sizeof(int)],
                             sizeof(struct sockaddr_storage));
            admin->initialized = true;
        }
        event_base_loopbreak(admin->eventBase);
        return;
    }

    struct Allocator* tempAllocator = admin->allocator->child(admin->allocator);
    handleRequestFromChild(admin, buffer, amount, tempAllocator);
    tempAllocator->free(tempAllocator);
}
Ejemplo n.º 14
0
/** Called when the request allocator is freed. */
static int removeReqFromSet(struct Allocator_OnFreeJob* job)
{
    struct Request* req = Identity_check((struct Request*) job->userData);
    struct Hermes* h = Identity_check(req->hermes);
    int index = Map_RequestSet_indexForHandle(req->handle, &h->requestSet);
    if (index > -1) {
        Map_RequestSet_remove(index, &h->requestSet);
    } else {
        Log_error(h->logger, "request with handle [%u] missing from set", req->handle);
    }
    return 0;
}
Ejemplo n.º 15
0
/**
 * Doesn't read more than maxRead bytes into buf[*have..bufSize]
 * Increments *have by amount of read bytes
 *
 * Buffer mustn't be full, and maxRead > 0
 *
 * return values:
 * n>0: read n new bytes
 *  -1: eof/network or read error - closed
 *  -2: EAGAIN
 */
static int inFromChildFillBuffer(struct Admin* admin,
                                 void *buf,
                                 uint32_t bufSize,
                                 uint32_t* have,
                                 uint32_t maxRead)
{
    char *charBuf = (char*) buf;
    Assert_true(*have < bufSize);
    Assert_true(maxRead > 0);

    if (maxRead > bufSize - *have) {
        maxRead = bufSize - *have;
    }

    Assert_always(maxRead > 0);
    Assert_always(maxRead <= INT_MAX);

    errno = 0;
    ssize_t amount = read(admin->inFd, charBuf + *have, maxRead);

    if (amount < 0 && (EAGAIN == errno || EWOULDBLOCK == errno)) {
        return -2;
    } else if (0 == amount) {
        Log_error(admin->logger, "Connection to admin process closed unexpectedly");
        adminClosePipes(admin);
        return -1;
    } else if (amount < 0) {
        Log_error(admin->logger, "Broken pipe to admin process, [%s]", strerror(errno));
        adminClosePipes(admin);
        return -1;
    }

    Assert_always(amount > 0);
    Assert_true(amount <= (ssize_t) maxRead);

    *have += amount;
    Assert_true(*have <= bufSize);

    return amount;
}
Ejemplo n.º 16
0
static void inFromChildInitialize(struct Admin* admin)
{
    uint8_t buffer[sizeof(struct sockaddr_storage) + sizeof(int) + 8];
    ssize_t amount = read(admin->inFd, buffer, sizeof(buffer));

    if (amount != sizeof(buffer)) {
        Log_error(admin->logger, "unexpected length");
        adminClosePipes(admin);
    } else if (memcmp(buffer, "abcd", 4)) {
        Log_error(admin->logger, "bad magic");
        adminClosePipes(admin);
    } else if (memcmp(&buffer[sizeof(struct sockaddr_storage) + sizeof(int) + 4], "wxyz", 4)) {
        Log_error(admin->logger, "bad magic");
        adminClosePipes(admin);
    } else {
        Bits_memcpyConst(&admin->addressLength, &buffer[4], sizeof(int));
        Bits_memcpyConst(&admin->address,
                        &buffer[4 + sizeof(int)],
                        sizeof(struct sockaddr_storage));
        admin->initialized = true;
    }
    event_base_loopbreak(admin->eventBase);
}
Ejemplo n.º 17
0
void upnp_set_error(struct action_event *event, int error_code,
		    const char *format, ...)
{
	event->status = -1;

	va_list ap;
	va_start(ap, format);
	event->request->ActionResult = NULL;
	event->request->ErrCode = UPNP_SOAP_E_ACTION_FAILED;
	vsnprintf(event->request->ErrStr, sizeof(event->request->ErrStr),
		  format, ap);

	va_end(ap);
	Log_error("upnp", "%s: %s\n", __FUNCTION__, event->request->ErrStr);
}
Ejemplo n.º 18
0
static void ethInterfaceSetBeacon(int ifNum, Dict* eth, struct Context* ctx)
{
    int64_t* beaconP = Dict_getInt(eth, String_CONST("beacon"));
    if (beaconP) {
        int64_t beacon = *beaconP;
        if (beacon > 3 || beacon < 0) {
            Log_error(ctx->logger, "interfaces.ETHInterface.beacon may only be 0, 1,or 2");
        } else {
            // We can cast beacon to an int here because we know it's small enough
            Log_info(ctx->logger, "Setting beacon mode on ETHInterface to [%d].", (int) beacon);
            Dict d = Dict_CONST(String_CONST("interfaceNumber"), Int_OBJ(ifNum),
                     Dict_CONST(String_CONST("state"), Int_OBJ(beacon), NULL));
            rpcCall(String_CONST("ETHInterface_beacon"), &d, ctx, ctx->alloc);
        }
    }
}
Ejemplo n.º 19
0
kern_return_t Exception_assign(Exception* self, 
							   mach_port_t task,
							   mach_port_t thread,
							   thread_state_t state,
							   exception_type_t type,
							   mach_exception_data_t code,
							   mach_msg_type_number_t codeCnt) {
	kern_return_t retVal = KERN_FAILURE;
	
	if (	(self == NULL)
		 || (task == TASK_NULL)
		 || (thread == THREAD_NULL)
		 || (state == NULL)) { 
		Log_invalidArgument("self: %p, task: %p, thread: %p, state: %p", 
							self,
							(void*) task,
							(void*) thread,
							state);
	
	} else {
		self->task = task;
		self->thread = thread;
		self->state = state;
		self->type = type;
		if (codeCnt > self->maxCount) {
			// resize data
			self->data = reallocf(self->data, codeCnt * sizeof(mach_exception_data_t));
			if (self->data) {
				self->maxCount = codeCnt;
			}
		}
		
		if (self->data == NULL) {
			Log_error("unable to allcoate memory");
			
		} else {
			self->count = codeCnt;
			(void) memcpy(self->data, code, self->count);
			retVal = KERN_SUCCESS;
		}
	}
	return retVal;
}
Ejemplo n.º 20
0
// only in parent
static void inFromChildRead(struct Admin* admin, struct Admin_Channel* channel)
{
    Assert_true(admin->messageHeader.length > 0);

    if (!channel->buffer) {
        Assert_true(NULL == channel->allocator);
        channel->allocator = admin->allocator->child(admin->allocator);
        channel->buffer = channel->allocator->malloc(MAX_API_REQUEST_SIZE, channel->allocator);
        Assert_true(0 == channel->bufferLen);
    }

    Assert_true(channel->bufferLen < MAX_API_REQUEST_SIZE);

    int amount = inFromChildFillBuffer(admin, channel->buffer, MAX_API_REQUEST_SIZE,
                                       &channel->bufferLen, admin->messageHeader.length);
    if (amount < 0) {
        return;
    }

    admin->messageHeader.length -= amount;
    if (0 == admin->messageHeader.length) {
        admin->haveMessageHeaderLen = 0;
    }

    inFromChildDecode(admin, channel);

    if (MAX_API_REQUEST_SIZE == channel->bufferLen) {
        // couldn't decode the request, but the buffer is full
        Log_error(admin->logger, "Request too large, closing channel [%u]",
                  admin->messageHeader.channelNum);
        adminChannelClose(admin, admin->messageHeader.channelNum);
    }

    if (0 == channel->bufferLen && channel->allocator) {
        // reached end of buffer, free it
        channel->allocator->free(channel->allocator);
        channel->allocator = NULL;
        channel->buffer = NULL;
    }
}
Ejemplo n.º 21
0
static int event_handler(Upnp_EventType EventType, void *event, void *userdata)
{
	struct upnp_device *priv = (struct upnp_device *) userdata;
	switch (EventType) {
	case UPNP_CONTROL_ACTION_REQUEST:
		handle_action_request(priv, event);
		break;

	case UPNP_CONTROL_GET_VAR_REQUEST:
		handle_var_request(priv, event);
		break;

	case UPNP_EVENT_SUBSCRIPTION_REQUEST:
		handle_subscription_request(priv, event);
		break;

	default:
		Log_error("upnp", "Unknown event type: %d", EventType);
		break;
	}
	return 0;
}
Ejemplo n.º 22
0
static UpnpWebFileHandle
webserver_open(const char *filename, enum UpnpOpenFileMode mode)
{
	if (mode != UPNP_READ) {
		Log_error("webserver",
			  "%s: ignoring request to open file for writing.",
			  filename);
		return NULL;
	}

	for (struct virtual_file *vf = virtual_files; vf; vf = vf->next) {
		if (strcmp(filename, vf->virtual_fname) == 0) {
			WebServerFile *file = malloc(sizeof(WebServerFile));
			file->pos = 0;
			file->len = vf->len;
			file->contents = vf->contents;
			return file;
		}
	}

	return NULL;
}
int output_gstreamer_init_master(void)
{
	GstBus *bus;
	GstElement *queue0;
	GstElement *decode_bin;
	GstElement *audio_sink0;

	player_ = gst_pipeline_new("audio_player_master");
	gst_data.source = gst_element_factory_make ("souphttpsrc", "source");
	gst_data.tee = gst_element_factory_make ("tee", "tee");
	queue0 = gst_element_factory_make ("queue", "queue");
	decode_bin = gst_element_factory_make ("decodebin", "decode_bin");
	gst_data.convert = gst_element_factory_make("audioconvert", "convert");
        audio_sink0 = gst_element_factory_make ("autoaudiosink", "audio_sink");

	if (!player_ || !gst_data.source || !gst_data.tee || !queue0 || !decode_bin || !gst_data.convert || !audio_sink0)
	{
		g_print ("Not all elements could be created.\n");
	}

	gst_bin_add_many (GST_BIN (player_), gst_data.source, gst_data.tee, queue0, decode_bin, gst_data.convert, audio_sink0, NULL);

	if (gst_element_link_many (gst_data.source, gst_data.tee, NULL) != TRUE)
	{
		g_print ("Elements could not be linked. 1\n");
		//gst_object_unref (player_);
	}

	if (gst_element_link_many (gst_data.tee, queue0, decode_bin, NULL) != TRUE)
	{
		g_print ("Elements could not be linked. 2\n");
		//gst_object_unref (player_);
	}

	if (gst_element_link_many (gst_data.convert, audio_sink0, NULL) != TRUE)
	{
		g_print ("Elements could not be linked. 3\n");
		//gst_object_unref (player_);
	}
	
	g_signal_connect (decode_bin, "pad-added", G_CALLBACK (master_pad_added_handler), NULL);

	bus = gst_pipeline_get_bus(GST_PIPELINE(player_));
	gst_bus_add_watch(bus, my_bus_callback, NULL);
	gst_object_unref(bus);

	if (audio_sink != NULL) {
		GstElement *sink = NULL;
		Log_info("gstreamer", "Setting audio sink to %s; device=%s\n",
			 audio_sink, audio_device ? audio_device : "");
		sink = gst_element_factory_make (audio_sink, "sink");
		if (sink == NULL) {
		  Log_error("gstreamer", "Couldn't create sink '%s'",
			    audio_sink);
		} else {
		  if (audio_device != NULL) {
		    g_object_set (G_OBJECT(sink), "device", audio_device, NULL);
		  }
		  g_object_set (G_OBJECT (player_), "audio-sink", sink, NULL);
		}
	}
	if (videosink != NULL) {
		GstElement *sink = NULL;
		Log_info("gstreamer", "Setting video sink to %s", videosink);
		sink = gst_element_factory_make (videosink, "sink");
		g_object_set (G_OBJECT (player_), "video-sink", sink, NULL);
	}

	if (gst_element_set_state(player_, GST_STATE_READY) ==
	    GST_STATE_CHANGE_FAILURE) {
		Log_error("gstreamer", "Error: pipeline doesn't become ready.");
	}
	return 0;
}
Ejemplo n.º 24
0
int main (int argc, char**argv)
{
	int ret = 0;
	int heartbeat_usec = 50000; //20Hz is ok by default
	uint64_t last_beat = 0;

	Log_info ("cloudvpn starting");
	Log (0, "You are using CloudVPN, which is Free software.");
	Log (0, "For more information please see the GNU GPL license,");
	Log (0, "which you should have received along with this program.");

	setup_sighandler (kill_cloudvpn);

	/*
	 * initialization
	 */

	if (!config_parse (argc, argv) ) {
		Log_error ("failed to parse config, terminating.");
		ret = 1;
		goto failed_config;
	}

	if (!config_get_int ("heartbeat", heartbeat_usec) )
		heartbeat_usec = 50000;
	Log_info ("heartbeat is set to %d usec", heartbeat_usec);

	timestamp_update(); //get initial timestamp

	status_init();
	route_init();
	squeue_init();
	network_init();

	if (poll_init() ) {
		Log_fatal ("poll initialization failed");
		ret = 2;
		goto failed_poll;
	}

	if (do_memlock() ) {
		Log_fatal ("locking process to memory failed");
		ret = 3;
		goto failed_poll;
	}

	if (comm_load() ) {
		Log_fatal ("failed to load comm data");
		ret = 4;
		goto failed_poll;
	}

	if (comm_init() ) {
		Log_fatal ("communication initialization failed");
		ret = 5;
		goto failed_comm;
	}

	if (gate_init() ) {
		Log_fatal ("gate initialization failed");
		ret = 6;
		goto failed_gate;
	}
	if (do_chroot() ) {
		Log_fatal ("chrooting failed");
		ret = 7;
		goto failed_sec;
	}

	if (do_switch_user() ) {
		Log_fatal ("user switch failed");
		ret = 8;
		goto failed_sec;
	}


	/*
	 * main loop
	 */

	Log_info ("initialization complete, entering main loop");

	last_beat = 0; //update immediately.

	while (!g_terminate) {

		timestamp_update();

		if ( (timestamp() - last_beat)
		        < (unsigned int) heartbeat_usec) {
			//poll more stuff
			poll_wait_for_event (heartbeat_usec
			                     - timestamp()
			                     + last_beat);
			//send the results
			comm_flush_data();
			gate_flush_data();
			continue;
		}

		last_beat = timestamp();

		gate_periodic_update();
		comm_periodic_update();
		route_periodic_update();

		status_try_export();
	}

	/*
	 * deinitialization
	 */

	Log_info ("shutting down");

failed_sec:

	gate_shutdown();

failed_gate:

	comm_shutdown();

failed_comm:

	if (poll_deinit() )
		Log_warn ("poll_deinit somehow failed!");

failed_poll:
failed_config:
	if (!ret) Log_info ("cloudvpn exiting gracefully");
	else Log_error ("cloudvpn exiting with code %d", ret);
	return ret;
}
Ejemplo n.º 25
0
int main(int argc, char **argv)
{
	int rc;
	struct upnp_device_descriptor *upnp_renderer;

	if (!process_cmdline(argc, argv)) {
		return EXIT_FAILURE;
	}

	if (show_version) {
		do_show_version();
		exit(EXIT_SUCCESS);
	}
	if (show_connmgr_scpd) {
		upnp_renderer_dump_connmgr_scpd();
		exit(EXIT_SUCCESS);
	}
	if (show_control_scpd) {
		upnp_renderer_dump_control_scpd();
		exit(EXIT_SUCCESS);
	}
	if (show_transport_scpd) {
		upnp_renderer_dump_transport_scpd();
		exit(EXIT_SUCCESS);
	}

	if (show_outputs) {
		output_dump_modules();
		exit(EXIT_SUCCESS);
	}

	init_logging(log_file);

	// Now we're going to start threads etc, which means we need
	// to become a daemon before that.

	// We need to open the pid-file now because relative filenames will
	// break if we're becoming a daemon and cwd changes.
	FILE *pid_file_stream = NULL;
	if (pid_file) {
		pid_file_stream = fopen(pid_file, "w");
	}
	if (daemon_mode) {
		daemon(0, 0);  // TODO: check for daemon() in configure.
	}
	if (pid_file_stream) {
		fprintf(pid_file_stream, "%d\n", getpid());
		fclose(pid_file_stream);
	}

#if !GLIB_CHECK_VERSION(2, 32, 0)
	// Only older version of glib require this.
	if (!g_thread_get_initialized()) {
		g_thread_init(NULL);
	}
#endif

	upnp_renderer = upnp_renderer_descriptor(friendly_name, uuid);
	if (upnp_renderer == NULL) {
		return EXIT_FAILURE;
	}

	rc = output_init(output);
	if (rc != 0) {
		Log_error("main",
			  "ERROR: Failed to initialize Output subsystem");
		return EXIT_FAILURE;
	}

	struct upnp_device *device;
	if (listen_port != 0 &&
	    (listen_port < 49152 || listen_port > 65535)) {
		// Somewhere obscure internally in libupnp, they clamp the
		// port to be outside of the IANA range, so at least 49152.
		// Instead of surprising the user by ignoring lower port
		// numbers, complain loudly.
		Log_error("main", "Parameter error: --port needs to be in "
			  "range [49152..65535] (but was set to %d)",
			  listen_port);
		return EXIT_FAILURE;
	}
	device = upnp_device_init(upnp_renderer, ip_address, listen_port);
	if (device == NULL) {
		Log_error("main", "ERROR: Failed to initialize UPnP device");
		return EXIT_FAILURE;
	}

	upnp_transport_init(device);
	upnp_control_init(device);

	if (show_devicedesc) {
		// This can only be run after all services have been
		// initialized.
		char *buf = upnp_create_device_desc(upnp_renderer);
		assert(buf != NULL);
		fputs(buf, stdout);
		exit(EXIT_SUCCESS);
	}

	if (Log_info_enabled()) {
		upnp_transport_register_variable_listener(log_variable_change,
							  (void*) "transport");
		upnp_control_register_variable_listener(log_variable_change,
							(void*) "control");
	}

	// Write both to the log (which might be disabled) and console.
	Log_info("main", "Ready for rendering.");
	fprintf(stderr, "Ready for rendering.\n");

	output_loop();

	// We're here, because the loop exited. Probably due to catching
	// a signal.
	Log_info("main", "Exiting.");
	upnp_device_shutdown(device);

	return EXIT_SUCCESS;
}
Ejemplo n.º 26
0
int main(int argc, char **argv)
{
	int rc;
	struct upnp_device_descriptor *upnp_renderer;

#if !GLIB_CHECK_VERSION(2,32,0)
	g_thread_init (NULL);  // Was necessary < glib 2.32, deprecated since.
#endif

	if (!process_cmdline(argc, argv)) {
		return EXIT_FAILURE;
	}

	if (show_version) {
		do_show_version();
		exit(EXIT_SUCCESS);
	}
	if (show_connmgr_scpd) {
		upnp_renderer_dump_connmgr_scpd();
		exit(EXIT_SUCCESS);
	}
	if (show_control_scpd) {
		upnp_renderer_dump_control_scpd();
		exit(EXIT_SUCCESS);
	}
	if (show_transport_scpd) {
		upnp_renderer_dump_transport_scpd();
		exit(EXIT_SUCCESS);
	}

	if (show_outputs) {
		output_dump_modules();
		exit(EXIT_SUCCESS);
	}

	init_logging(log_file);

	// Now we're going to start threads etc, which means we need
	// to become a daemon before that.

	// We need to open the pid-file now because relative filenames will
	// break if we're becoming a daemon and cwd changes.
	FILE *pid_file_stream = NULL;
	if (pid_file) {
		pid_file_stream = fopen(pid_file, "w");
	}
	if (daemon_mode) {
		daemon(0, 0);  // TODO: check for daemon() in configure.
	}
	if (pid_file_stream) {
		fprintf(pid_file_stream, "%d\n", getpid());
		fclose(pid_file_stream);
	}

	if (show_devicedesc) {
		// This can only be run after all services have been
		// initialized.
		char *buf = upnp_create_device_desc(upnp_renderer);
		assert(buf != NULL);
		fputs(buf, stdout);
		exit(EXIT_SUCCESS);
	}
	struct upnp *upnp = upnp_start(friendly_name, uuid, "1234", ip_address, listen_port, output);
	if (upnp == NULL) {
		Log_error("main", "ERROR: Failed to initialize UPnP device");
		return EXIT_FAILURE;
	}

	// Write both to the log (which might be disabled) and console.
	Log_info("main", "Ready for rendering.");
	fprintf(stderr, "Ready for rendering.\n");

	output_loop();

	// We're here, because the loop exited. Probably due to catching
	// a signal.
	Log_info("main", "Exiting.");
	upnp_stop(upnp);

	return EXIT_SUCCESS;
}
Ejemplo n.º 27
0
static void runTest0(char** prefixes,
                     char** exceptions4,
                     char** exceptions6,
                     char** expectedOut4,
                     char** expectedOut6,
                     struct Allocator* alloc,
                     struct Log* log)
{
    struct RouteGen* rg = RouteGen_new(alloc, log);
    for (int i = 0; prefixes[i]; i++) {
        RouteGen_addPrefix(rg, mkSockaddr(prefixes[i], alloc));
    }
    for (int i = 0; exceptions4 && exceptions4[i]; i++) {
        RouteGen_addException(rg, mkSockaddr(exceptions4[i], alloc));
    }
    for (int i = 0; exceptions6 && exceptions6[i]; i++) {
        RouteGen_addException(rg, mkSockaddr(exceptions6[i], alloc));
    }
    Dict* routes = RouteGen_getGeneratedRoutes(rg, alloc);
    List* routes4 = Dict_getList(routes, String_CONST("ipv4"));
    List* routes6 = Dict_getList(routes, String_CONST("ipv6"));
    if (expectedOut4) {
        for (int i = 0; expectedOut4[i]; i++) {
            Log_debug(log, "%s\n", expectedOut4[i]);
        }
        for (int i = 0; i < List_size(routes4); i++) {
            Log_debug(log, "%s\n", List_getString(routes4, i)->bytes);
        }

        Assert_true(!expectedOut4[List_size(routes4)]);
        for (int i = 0; i < List_size(routes4); i++) {
            String* str = List_getString(routes4, i);
            Assert_true(str);
            Assert_true(expectedOut4[i]);
            if (CString_strncmp(expectedOut4[i], str->bytes, str->len)) {
                Log_error(log, "Fail\nexpected: %s\nGot:      %s\n", expectedOut4[i], str->bytes);
                Assert_failure("fail");
            }
        }
    } else {
        Assert_true(!List_size(routes4));
    }
    if (expectedOut6) {
        for (int i = 0; expectedOut6[i]; i++) {
            Log_debug(log, "%s\n", expectedOut6[i]);
        }
        for (int i = 0; i < List_size(routes6); i++) {
            Log_debug(log, "%s\n", List_getString(routes6, i)->bytes);
        }

        Assert_true(!expectedOut6[List_size(routes6)]);
        for (int i = 0; i < List_size(routes6); i++) {
            String* str = List_getString(routes6, i);
            Assert_true(str);
            Assert_true(expectedOut6[i]);
            if (CString_strncmp(expectedOut6[i], str->bytes, str->len)) {
                Log_error(log, "Fail\nexpected: %s\nGot:      %s\n", expectedOut6[i], str->bytes);
                Assert_failure("fail");
            }
        }
    } else {
        Assert_true(!List_size(routes6));
    }
}
Ejemplo n.º 28
0
// only in parent
static void inFromChild(evutil_socket_t socket, short eventType, void* vcontext)
{
    struct Admin* admin = (struct Admin*) vcontext;

    if (!admin->initialized) {
        inFromChildInitialize(admin);
        return;
    }

    int newMessage = 0;

    if (admin->haveMessageHeaderLen < Admin_MessageHeader_SIZE) {
        int amount = inFromChildFillBuffer(admin, &admin->messageHeader, Admin_MessageHeader_SIZE,
                                           &admin->haveMessageHeaderLen, Admin_MessageHeader_SIZE);
        if (amount < 0) {
            return;
        }

        if (admin->haveMessageHeaderLen == Admin_MessageHeader_SIZE) {
            newMessage = 1;
            // got complete header
            if (admin->pipeMagic != admin->messageHeader.magic) {
                Log_error(admin->logger, "wrong magic from admin process");
                adminClosePipes(admin);
                return;
            }
            if (admin->messageHeader.length > MAX_MESSAGE_SIZE) {
                Log_error(admin->logger, "message from admin process too large");
                adminClosePipes(admin);
                return;
            }
            if (0 == admin->messageHeader.length) {
                // empty message -> close channel
                adminChannelHandleClose(admin);
                admin->haveMessageHeaderLen = 0;
                return;
            }
        }
    }

    if (admin->haveMessageHeaderLen == Admin_MessageHeader_SIZE) {
        // handle non empty message data
        struct Admin_Channel* channel =
            adminChannelFindById(admin, admin->messageHeader.channelNum);
        if (!channel) {
            if (newMessage) {
                Log_info(admin->logger,
                         "message from admin process on invalid channel [%u]",
                         admin->messageHeader.channelNum);
                // send close
                adminChannelSendData(admin, admin->messageHeader.channelNum, NULL, 0);
            }
            /* ignore data */
            inFromChildSkipMmsg(admin);
        } else {
            switch (channel->state) {
            case Admin_ChannelState_CLOSED:
                channel->state = Admin_ChannelState_OPEN;
                inFromChildRead(admin, channel);
                break;
            case Admin_ChannelState_OPEN:
                inFromChildRead(admin, channel);
                break;
            case Admin_ChannelState_WAIT_FOR_CLOSE:
                /* ignore data */
                inFromChildSkipMmsg(admin);
                break;
            }
        }
    }
}
Ejemplo n.º 29
0
static int handle_subscription_request(struct upnp_device *priv,
                                       struct Upnp_Subscription_Request
                                              *sr_event)
{
	struct service *srv;
	int rc;

	assert(priv != NULL);

	Log_info("upnp", "Subscription request for %s (%s)",
		 sr_event->ServiceId, sr_event->UDN);

	srv = find_service(priv->upnp_device_descriptor, sr_event->ServiceId);
	if (srv == NULL) {
		Log_error("upnp", "%s: Unknown service '%s'", __FUNCTION__,
			  sr_event->ServiceId);
		return -1;
	}

	int result = -1;
	ithread_mutex_lock(&(priv->device_mutex));

	// There is really only one variable evented: LastChange
	const char *eventvar_names[] = {
		"LastChange",
		NULL
	};
	const char *eventvar_values[] = {
		NULL, NULL
	};

	// Build the current state of the variables as one gigantic initial
	// LastChange update.
	ithread_mutex_lock(srv->service_mutex);
	const int var_count =
		VariableContainer_get_num_vars(srv->variable_container);
	// TODO(hzeller): maybe use srv->last_change directly ?
	upnp_last_change_builder_t *builder = UPnPLastChangeBuilder_new(srv->event_xml_ns);
	for (int i = 0; i < var_count; ++i) {
		const char *name;
		const char *value =
			VariableContainer_get(srv->variable_container, i, &name);
		// Send over all variables except "LastChange" itself. Also all
		// A_ARG_TYPE variables are not evented.
		if (value && strcmp("LastChange", name) != 0
		    && strncmp("A_ARG_TYPE_", name, strlen("A_ARG_TYPE_")) != 0) {
			UPnPLastChangeBuilder_add(builder, name, value);
		}
	}
	ithread_mutex_unlock(srv->service_mutex);
	char *xml_value = UPnPLastChangeBuilder_to_xml(builder);
	Log_info("upnp", "Initial variable sync: %s", xml_value);
	eventvar_values[0] = xmlescape(xml_value, 0);
	free(xml_value);
	UPnPLastChangeBuilder_delete(builder);

	rc = UpnpAcceptSubscription(priv->device_handle,
				    sr_event->UDN, sr_event->ServiceId,
				    eventvar_names, eventvar_values, 1,
				    sr_event->Sid);
	if (rc == UPNP_E_SUCCESS) {
		result = 0;
	} else {
		Log_error("upnp", "Accept Subscription Error: %s (%d)",
			  UpnpGetErrorMessage(rc), rc);
	}

	ithread_mutex_unlock(&(priv->device_mutex));

	free((char*)eventvar_values[0]);

	return result;
}
Ejemplo n.º 30
0
static int handle_action_request(struct upnp_device *priv,
                                 struct Upnp_Action_Request *ar_event)
{
	struct service *event_service;
	struct action *event_action;

	event_service = find_service(priv->upnp_device_descriptor,
				     ar_event->ServiceID);
	event_action = find_action(event_service, ar_event->ActionName);

	if (event_action == NULL) {
		Log_error("upnp", "Unknown action '%s' for service '%s'",
			  ar_event->ActionName, ar_event->ServiceID);
		ar_event->ActionResult = NULL;
		ar_event->ErrCode = 401;
		return -1;
	}

	// We want to send the LastChange event only after the action is
	// finished - just to be conservative, we don't know how clients
	// react to get LastChange notifictions while in the middle of
	// issuing an action.
	//
	// So we nest the change collector level here, so that we only send the
	// LastChange after the action is finished ().
	//
	// Note, this is, in fact, only a preparation and not yet working as
	// described above: we are still in the middle
	// of executing the event-callback while sending the last change
	// event implicitly when calling UPnPLastChangeCollector_finish() below.
	// It would be good to enqueue the upnp_device_notify() after
	// the action event is finished.
	if (event_service->last_change) {
		ithread_mutex_lock(event_service->service_mutex);
		UPnPLastChangeCollector_start(event_service->last_change);
		ithread_mutex_unlock(event_service->service_mutex);
	}

#ifdef ENABLE_ACTION_LOGGING
	{
		char *action_request_xml = NULL;
		if (ar_event->ActionRequest) {
			action_request_xml = ixmlDocumenttoString(
					   ar_event->ActionRequest);
		}
		Log_info("upnp", "Action '%s'; Request: %s",
			 ar_event->ActionName, action_request_xml);
		free(action_request_xml);
	}
#endif

	if (event_action->callback) {
		struct action_event event;
		int rc;
		event.request = ar_event;
		event.status = 0;
		event.service = event_service;
                event.device = priv;

		rc = (event_action->callback) (&event);
		if (rc == 0) {
			ar_event->ErrCode = UPNP_E_SUCCESS;
#ifdef ENABLE_ACTION_LOGGING
			if (ar_event->ActionResult) {
				char *action_result_xml = NULL;
				action_result_xml = ixmlDocumenttoString(
						ar_event->ActionResult);
				Log_info("upnp", "Action '%s' OK; Response %s",
					 ar_event->ActionName,
					 action_result_xml);
				free(action_result_xml);
			} else {
				Log_info("upnp", "Action '%s' OK",
					 ar_event->ActionName);
			}
#endif
		}
		if (ar_event->ActionResult == NULL) {
			ar_event->ActionResult =
			    UpnpMakeActionResponse(ar_event->ActionName,
						   event_service->service_type,
						   0, NULL);
		}
	} else {
		Log_error("upnp",
			  "Got a valid action, but no handler defined (!)\n"
			  "  ErrCode:    %d\n"
			  "  Socket:     %d\n"
			  "  ErrStr:     '%s'\n"
			  "  ActionName: '%s'\n"
			  "  DevUDN:     '%s'\n"
			  "  ServiceID:  '%s'\n",
			  ar_event->ErrCode, ar_event->Socket, ar_event->ErrStr,
			  ar_event->ActionName, ar_event->DevUDN,
			  ar_event->ServiceID);
		ar_event->ErrCode = UPNP_E_SUCCESS;
	}

	if (event_service->last_change) {   // See comment above.
		ithread_mutex_lock(event_service->service_mutex);
		UPnPLastChangeCollector_finish(event_service->last_change);
		ithread_mutex_unlock(event_service->service_mutex);
	}
	return 0;
}