Exemplo n.º 1
0
/******************************************************************************
	Start obsluhy klienta

	Inspirace (vytvoreni socketu, bind):
	http://beej.us/guide/bgnet/output/html/multipage/clientserver.html#datagram
*******************************************************************************/
int Client::start(Opt *options, struct sockaddr_storage client_addr, int index, char *buf, int numbytes, int mtu)
{
	// Generovani nahodneho cisla pro port, na kterem bude klient obsluhovan
	srand (getpid());
	int port = rand() % MAX_PORT + MIN_PORT;

	client_port = to_string(port);
	service_ip = options->address_at(index);

	int sockfd;
	struct addrinfo hints, *servinfo, *p;
	int rv;
	socklen_t addr_len;
	char s[INET6_ADDRSTRLEN];

	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_DGRAM;

	signal(SIGINT, client_signal_reaction); // Registrace funkce pro odchyt signalu

	if ((rv = getaddrinfo(service_ip.c_str(), client_port.c_str(), &hints, &servinfo)) != 0)
	{
		cerr << "Error - Service " << service_ip << ", " << client_port << gai_strerror(rv) << endl;
		return EXIT_FAILURE;
	}

	for(p = servinfo; p != NULL; p = p->ai_next)
	{
		if ((sockfd = socket(p->ai_family, p->ai_socktype,
			p->ai_protocol)) == -1)
		{
			continue;
		}

		if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1)
		{
			close(sockfd);
			continue;
		}

		break;
	}

	if (p == NULL)
	{
		cerr << "Error - Service " << service_ip << ", " << client_port << " - failed to bind socket" << endl;
		return EXIT_FAILURE;
	}

	freeaddrinfo(servinfo);

	client_socket = sockfd; // Ulozim si deskr. socketu

	// Nastavi se vychozi timeout socketu
	if((set_socket_timeout(options, IMPLICIT_TIMEOUT)) == SET_FAILED) return EXIT_FAILURE;

	// ulozim si klientovu IP pro potreby vypisu informacnich hlasek
	string client_ip = inet_ntop(client_addr.ss_family, get_in_addr((struct sockaddr *)&client_addr), s, sizeof s);

	mtu_size = mtu; // Ulozim si MTU

	// Cinnost obsluhy serveru
	string err_msg;
	unsigned int data_counter = 0;		// Pocitadlo dat
	unsigned int block_counter = 0;		// Pocitadlo bloku
	int data_len;						// Pocet odeslanych B
	int mode;							// Mod prenosu
	int tryouts = 0;					// Pocet pokusu o znovu navazani komunikace
	bool reading_data = false;			// Flag cteni dat
	bool writing_data = false;			// Flag zapisu dat
	int ack;							// Cislo potvrzeneho bloku
	int type;							// Typ paketu
	int file_status;					// Info o uspesnosti operace se souborem
	int bytes_write;					// Pocet zapsanych bajtu
	int block_num;						// Cislo bloku
	int recv_status;					// Pocet prijatych B pri volani funkce recvfrom()
	char *file_buf;						// Buffer pro nacitani dat ze souboru
	int file_buf_size;// Velikost bufferu

	File *f = new File(); // Nova instance objektu pro praci se soubory

	while(1)
	{// Smycka obsluhy klienta

	   if(writing_data == true) type = packet_type(file_buf); // buffer na heapu
	   else type = packet_type(buf); // buffer na zasobniku

	   switch(type)
	   {// Podle typu paketu se provadi dana operace

			case RRQ:
			{// Zadost o cteni
				get_filename(buf); // ukladani jmena souboru

				// Zjisti se mod prenosu

				mode = transfer_mode(buf);

				if(mode == UNKNOWN_MODE)
				{// neznamy mod
				   err_msg = "Unknown mode";
				   send_error(sockfd, client_addr, err_msg, ERROR_IL);
				   cout << current_time() << client_ip << " Unknown mode, operation aborted" << endl;
					
					clean_sources(f, sockfd);
					return 1;
				}
				else if(mode == NETASCII)
				{
					cout << current_time() + client_ip + " Requested READ of " << filename << " [netascii]"<< endl;
				}
				else if(mode == OCTET)
				{
					cout << current_time() + client_ip + " Requested READ of " << filename << " [octet]"<< endl;
				}

				// Otevre se soubor pro cteni
				file_status = f->open(filename, options->working_path(), FILE_IN, mode_tr);

				if(file_status == NOT_FOUND)
				{// Soubor nebyl nalezen
					err_msg = "File not found";
					send_error(sockfd, client_addr, err_msg, ERROR_NF);
					cout << current_time() + client_ip + " File " << filename << " not found, operation aborted" << endl;

					clean_sources(f, sockfd);
					return 1;
				}
				else if(file_status == PERM_DEN)
				{// Nedostatecne opravneni
					err_msg = "Permission denided";
					send_error(sockfd, client_addr, err_msg, ERROR_AV);
					cout << current_time() << client_ip << " Permission denided, operation aborted" << endl;

					clean_sources(f, sockfd);
					return EXIT_FAILURE;
				}

				// Zjisti se pritomnost rozsireni

				if(opt_extension(buf, numbytes, options, f) == EXTENSION)
				{// request obsahuje options
					send_oack(sockfd, client_addr);
					
					reading_data = true;

					// Alokace bufferu pro nacitani souboru
					if(block_size.used == true)
					{// byla specifikovana velikost bloku
						file_buf = new char[block_size.value + 1];
						file_buf_size = block_size.value + 1;

						if(f->get_file_size() > MAX_BLOCK_COUNT * block_size.value)
						{// Soubor je prilis velky na prenos pres tftp
							err_msg = "File is too large to send";
							send_error(sockfd, client_addr, err_msg, ERROR_DF);
							cout << current_time() + client_ip + " File is too large to send. Operation aborted\n";
							
							clean_sources(f, sockfd);
							return EXIT_FAILURE;
						}
					}
					else
					{// mezi parametry nebyla velikost bloku, uvazuje se standardni
						file_buf = new char[STANDARD_BLOCK + 1];
						file_buf_size = STANDARD_BLOCK + 1;
					}
				}
				else
				{// bez parametru, posilani prvnich dat

					if(f->get_file_size() > MAX_BLOCK_COUNT * STANDARD_BLOCK)
					{// Soubor je prilis velky na prenos pres tftp
						err_msg = "File is too large to send";
						send_error(sockfd, client_addr, err_msg, ERROR_IL);
						cout << current_time() + client_ip + " File is too large to send. Operation aborted\n";
						
						clean_sources(f, sockfd);
						return 1;
					}

					// Alokace bufferu pro nacitani souboru - standardni velikost
					file_buf = new char[STANDARD_BLOCK + 1];

					reading_data = true;

					cout << current_time() + client_ip + " Sending DATA\n";

					// poslou se prvni data
					data_len = send_data(sockfd, client_addr, 1, STANDARD_BLOCK, f, file_buf);
					data_counter += data_len;

					if(data_len < STANDARD_BLOCK)
					{// Prvni blok je zaroven i posledni, tim konci cinnost
						reading_data = false;
					}
				}

				break;
			}

			case WRQ:
			{// Zadost o zapis

				get_filename(buf); // ulozim jmeno souboru

				// Zjistim mod prenosu

				mode = transfer_mode(buf);

				if(mode == UNKNOWN_MODE)
				{// neznamy mod
					err_msg = "Unknown transfer mode";
					send_error(sockfd, client_addr, err_msg, ERROR_IL);
					break;
				}
				else if(mode == NETASCII)
				{
					cout << current_time() << client_ip << " Requested WRITE of " << filename << " [netascii]" << endl;
				}
				else if(mode == OCTET)
				{
					cout << current_time() << client_ip << " Requested WRITE of " << filename << " [octet]" << endl;
				}

				// Otevre se soubor pro zapis

				if(mode == OCTET)
				{
					file_status = f->open(filename, options->working_path(), FILE_OUT, OCTET);
				}
				else if(mode == NETASCII)
				{
					file_status = f->open(filename, options->working_path(), FILE_OUT, NETASCII);
				}

				if(file_status == FILE_EXISTS)
				{// Soubor j*z existuje
					err_msg = "File already exists";
					send_error(sockfd, client_addr, err_msg, ERROR_AE);
					cout << current_time() << client_ip << " File " << filename << " already exists, operation aborted" << endl;
					clean_sources(f, sockfd);
					return 1;
				}
				else if(file_status == CANNOT_OPEN)
				{// Nelze otevrit
					err_msg = "Cannot open file for writing";
					send_error(sockfd, client_addr, err_msg, ERROR_IL);
					cout << current_time() << client_ip << " Cannot opet file " << filename << " for writing, operation aborted" << endl;
					clean_sources(f, sockfd);
					return 1;
				}

				// Zjisti se rozsireni

				if(opt_extension(buf, numbytes, options, f) == EXTENSION)
				{// request obsahuje options
					send_oack(sockfd, client_addr);

					// Alokace bufferu pro nacitani souboru
					if(block_size.used == true)
					{// byla specifikovana velikost bloku
						file_buf = new char[block_size.value + 10];
						file_buf_size = block_size.value + 10;
					}
					else
					{// mezi parametry nebyla velikost bloku, uvazuje se standardni
						file_buf = new char[STANDARD_BLOCK + 10];
						file_buf_size = STANDARD_BLOCK + 10;
					}	  

					writing_data = true;
					cout << current_time() + client_ip + " Receiving DATA\n";
				}
				else
				{// Bez rozsireni, zasle se ack 0
					send_ack(sockfd, client_addr, 0);

					// Alokace bufferu pro zapis souboru - standardni velikost
					file_buf = new char[STANDARD_BLOCK + 10];
					file_buf_size = STANDARD_BLOCK + 10;

					writing_data = true;
					cout << current_time() + client_ip + " Receiving DATA\n";
				}

				break;
			}

			case DATA:
			{// Datovy paket od klienta

				if(writing_data == true)
				{// Probiha prenos
					block_num = ack_number(file_buf); // zjisti se cislo bloku

					if((block_counter + 1) != block_num)
					{// Prisel blok, ktery nenavazuje na predchozi

						err_msg = "Error while file transfer";
						send_error(sockfd, client_addr, err_msg, ERROR_IL);

						break;
					}

					int actual_block;

					if(block_size.used == true)
					{// Pouziva se nestandardni velikost bloku
						actual_block = block_size.value;
						bytes_write = recv_data(file_buf, numbytes, actual_block, f); // zapisou se data
					}
					else
					{// Standardni velikost bloku
						actual_block = STANDARD_BLOCK;
						bytes_write = recv_data(file_buf, numbytes, actual_block, f); // zapisou se data
					}

					if(bytes_write >= 0)
					{// Zapis byl uspesny, potvrdi se klientovi
						send_ack(sockfd, client_addr, block_num);

						block_counter++; // zvetsi se pocitadlo ulozenych bloku
						data_counter += bytes_write; // pricte se pocet ulozenych dat k pocitadlu

						if((numbytes - 4) < actual_block)
						{// dat bylo min nez je velikost bloku
							writing_data = false;

							f->close_file(FILE_OUT); // uzavre se soubor pro zapis

							cout << current_time() << client_ip << " File " << filename << " has been stored [" << data_counter << " B, " << block_counter << " blocks]" << endl;

							clean_sources(f, sockfd);

							return EXIT_FAILURE;
						}
					}
					else if(bytes_write == READ_ERR)
					{// Zapis nebyl uspesny
						err_msg = "Error while writing to file";
						send_error(sockfd, client_addr, err_msg, ERROR_IL);
						clean_sources(f, sockfd);
						return EXIT_FAILURE;
					}
				}

				break;
			}

			case ACK:
			{// Potvrzeni od klienta, ze obdrzel konkretni datovy paket

				ack = ack_number(buf);

				if(ack == 0) cout << current_time() + client_ip + " Sending DATA\n";

				if(reading_data == true)
				{// prenos jeste nebyl dokoncen

					if(block_size.used == true)
					{// Pouziva se nestandardni velikost bloku
						data_len = send_data(sockfd, client_addr, ack + 1, block_size.value, f, file_buf);

						if(data_len == SEND_FAIL)
						{// Chyba pri odesilani
							cerr << current_time() << client_ip << " Error in sendto, operation aborted" << endl;
							clean_sources(f, sockfd);
							return EXIT_FAILURE;
						}
						else if(data_len < block_size.value) reading_data = false;
					}
					else
					{// Standardni velikost bloku
						data_len = send_data(sockfd, client_addr, ack + 1, STANDARD_BLOCK, f, file_buf);

						if(data_len == SEND_FAIL)
						{// Chyba pri odesilani
							cerr << current_time() << client_ip << " Error in sendto, operation aborted" << endl;
							clean_sources(f, sockfd);
							return EXIT_FAILURE;
						}
						else if(data_len < STANDARD_BLOCK) reading_data = false;
					}

					data_counter += data_len;
				}
				else
				{// Prenos byl dokoncen
					cout << current_time() << client_ip << " File " << filename << " has been sent [" << data_counter << " B, " << ack << " blocks]\n";

					clean_sources(f, sockfd);

					return EXIT_SUCCESS;
				}

				break;
			}

			case ERR:
			{// Error paket

				int err;

				if(reading_data == true)
				{// Klient poslal error pri cteni dat
					err = recv_error(buf);

					switch(err)
					{
						case ERROR_UN:
						{// Unknown transfer ID

							f->close_file(FILE_IN);
							cout << current_time() << client_ip << " Client aborted file read (transport error)" << endl;
							return EXIT_FAILURE;
						}

						case ERROR_DF:
						{// Disk full
							f->close_file(FILE_IN);
							cout << current_time() << client_ip << " Client aborted file read (too large)" << endl;
							return EXIT_FAILURE;
						}

						case ERROR_ND:
						{// Nedefinovana chyba
							f->close_file(FILE_IN);
							cout << current_time() << client_ip << " Client aborted file read (undefined error)" << endl;
							return EXIT_FAILURE;
						}
					}
				}
				else if(writing_data == true)
				{// Klient poslal error pri zapisu dat
					err = recv_error(buf);

					switch(err)
					{
						case ERROR_UN:
						{// Unknown transfer ID
							f->close_file(FILE_OUT);
							cout << current_time() << client_ip << " Client aborted file write" << endl;
							return EXIT_FAILURE;
						}

						case ERROR_ND:
						{// Nedefinovana chyba
							f->close_file(FILE_OUT);
							cout << current_time() << client_ip << " Client aborted file read (undefined error)" << endl;
							return EXIT_FAILURE;
						}
					}
				}

				break;
			}

			case UNKNOWN_OPCODE:
			{// Neznamy opcode
				err_msg = "Unknown request";
				send_error(sockfd, client_addr, err_msg, ERROR_IL);
				clean_sources(f, sockfd);
				return EXIT_FAILURE;
			}

		}// konec switch(type)

		if(writing_data == true)
		{// Pokud probiha zapis, pouziva se vetsi buffer alokovany na halde
			recv_status = recv_packet(sockfd, client_addr, file_buf, file_buf_size);
		}
		else
		{// Pri cteni staci mensi velikost na zasobniku
			recv_status = recv_packet(sockfd, client_addr, buf, BUFSIZE);
		}

		if(recv_status == TIMEOUT_ELAPSED)
		{// Vyprsel cas cekani, probehne 3x pokus o znovu navazani komunikace
			tryouts++;

			if(tryouts == 3)
			{// Probehly tri pokusy o znovu navazani komunikace
				cout << current_time() << client_ip << " Timeout elapsed, operation aborted" << endl;
				clean_sources(f, sockfd);
				return 1;
			}
			else
			{// Probehne pokus
				cout << current_time() << client_ip << " Timeout elapsed, retrying..." << endl;
			}
		}
		else
		{// Byl normalne prijat paket
			numbytes = recv_status;
			tryouts = 0; // Vynuluje se pocitadlo neuspesnych pokusu
		}
	}
}
Exemplo n.º 2
0
/**
 * Handle incoming PSYC message.
 *
 * @param recv  Receive handle.
 * @param msg   The message.
 *
 * @return #GNUNET_OK on success,
 *         #GNUNET_SYSERR on receive error.
 */
int
GNUNET_PSYC_receive_message (struct GNUNET_PSYC_ReceiveHandle *recv,
                             const struct GNUNET_PSYC_MessageHeader *msg)
{
  uint16_t size = ntohs (msg->header.size);
  uint32_t flags = ntohl (msg->flags);
  uint64_t message_id;

  GNUNET_PSYC_log_message (GNUNET_ERROR_TYPE_DEBUG,
                           (struct GNUNET_MessageHeader *) msg);

  if (GNUNET_PSYC_MESSAGE_STATE_START == recv->state)
  {
    recv->message_id = GNUNET_ntohll (msg->message_id);
    recv->flags = flags;
    recv->slave_key = msg->slave_key;
    recv->mod_value_size = 0;
    recv->mod_value_size_expected = 0;
  }
  else if (GNUNET_ntohll (msg->message_id) != recv->message_id)
  {
    // FIXME
    LOG (GNUNET_ERROR_TYPE_WARNING,
         "Unexpected message ID. Got: %" PRIu64 ", expected: %" PRIu64 "\n",
         GNUNET_ntohll (msg->message_id), recv->message_id);
    GNUNET_break_op (0);
    recv_error (recv);
    return GNUNET_SYSERR;
  }
  else if (flags != recv->flags)
  {
    LOG (GNUNET_ERROR_TYPE_WARNING,
         "Unexpected message flags. Got: %lu, expected: %lu\n",
         flags, recv->flags);
    GNUNET_break_op (0);
    recv_error (recv);
    return GNUNET_SYSERR;
  }
  message_id = recv->message_id;

  uint16_t pos = 0, psize = 0, ptype, size_eq, size_min;

  for (pos = 0; sizeof (*msg) + pos < size; pos += psize)
  {
    const struct GNUNET_MessageHeader *pmsg
      = (const struct GNUNET_MessageHeader *) ((char *) &msg[1] + pos);
    psize = ntohs (pmsg->size);
    ptype = ntohs (pmsg->type);
    size_eq = size_min = 0;

    if (psize < sizeof (*pmsg) || sizeof (*msg) + pos + psize > size)
    {
      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                  "Dropping message of type %u with invalid size %u.\n",
                  ptype, psize);
      recv_error (recv);
      return GNUNET_SYSERR;
    }

    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Received message part of type %u and size %u from PSYC.\n",
                ptype, psize);
    GNUNET_PSYC_log_message (GNUNET_ERROR_TYPE_DEBUG, pmsg);

    switch (ptype)
    {
    case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD:
      size_min = sizeof (struct GNUNET_PSYC_MessageMethod);
      break;
    case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MODIFIER:
      size_min = sizeof (struct GNUNET_PSYC_MessageModifier);
      break;
    case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MOD_CONT:
    case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_DATA:
      size_min = sizeof (struct GNUNET_MessageHeader);
      break;
    case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_END:
    case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_CANCEL:
      size_eq = sizeof (struct GNUNET_MessageHeader);
      break;
    default:
      GNUNET_break_op (0);
      recv_error (recv);
      return GNUNET_SYSERR;
    }

    if (! ((0 < size_eq && psize == size_eq)
           || (0 < size_min && size_min <= psize)))
    {
      GNUNET_break_op (0);
      recv_error (recv);
      return GNUNET_SYSERR;
    }

    switch (ptype)
    {
    case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD:
    {
      struct GNUNET_PSYC_MessageMethod *meth
        = (struct GNUNET_PSYC_MessageMethod *) pmsg;

      if (GNUNET_PSYC_MESSAGE_STATE_START != recv->state)
      {
        LOG (GNUNET_ERROR_TYPE_WARNING,
             "Dropping out of order message method (%u).\n",
             recv->state);
        /* It is normal to receive an incomplete message right after connecting,
         * but should not happen later.
         * FIXME: add a check for this condition.
         */
        GNUNET_break_op (0);
        recv_error (recv);
        return GNUNET_SYSERR;
      }

      if ('\0' != *((char *) meth + psize - 1))
      {
        LOG (GNUNET_ERROR_TYPE_WARNING,
             "Dropping message with malformed method. "
             "Message ID: %" PRIu64 "\n", recv->message_id);
        GNUNET_break_op (0);
        recv_error (recv);
        return GNUNET_SYSERR;
      }
      recv->state = GNUNET_PSYC_MESSAGE_STATE_METHOD;
      break;
    }
    case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MODIFIER:
    {
      if (!(GNUNET_PSYC_MESSAGE_STATE_METHOD == recv->state
            || GNUNET_PSYC_MESSAGE_STATE_MODIFIER == recv->state
            || GNUNET_PSYC_MESSAGE_STATE_MOD_CONT == recv->state))
      {
        LOG (GNUNET_ERROR_TYPE_WARNING,
             "Dropping out of order message modifier (%u).\n",
             recv->state);
        GNUNET_break_op (0);
        recv_error (recv);
        return GNUNET_SYSERR;
      }

      struct GNUNET_PSYC_MessageModifier *mod
        = (struct GNUNET_PSYC_MessageModifier *) pmsg;

      uint16_t name_size = ntohs (mod->name_size);
      recv->mod_value_size_expected = ntohl (mod->value_size);
      recv->mod_value_size = psize - sizeof (*mod) - name_size;

      if (psize < sizeof (*mod) + name_size
          || '\0' != *((char *) &mod[1] + name_size - 1)
          || recv->mod_value_size_expected < recv->mod_value_size)
      {
        LOG (GNUNET_ERROR_TYPE_WARNING, "Dropping malformed modifier.\n");
        GNUNET_break_op (0);
        recv_error (recv);
        return GNUNET_SYSERR;
      }
      recv->state = GNUNET_PSYC_MESSAGE_STATE_MODIFIER;
      break;
    }
    case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MOD_CONT:
    {
      recv->mod_value_size += psize - sizeof (*pmsg);

      if (!(GNUNET_PSYC_MESSAGE_STATE_MODIFIER == recv->state
            || GNUNET_PSYC_MESSAGE_STATE_MOD_CONT == recv->state)
          || recv->mod_value_size_expected < recv->mod_value_size)
      {
        LOG (GNUNET_ERROR_TYPE_WARNING,
             "Dropping out of order message modifier continuation "
             "!(%u == %u || %u == %u) || %lu < %lu.\n",
             GNUNET_PSYC_MESSAGE_STATE_MODIFIER, recv->state,
             GNUNET_PSYC_MESSAGE_STATE_MOD_CONT, recv->state,
             recv->mod_value_size_expected, recv->mod_value_size);
        GNUNET_break_op (0);
        recv_error (recv);
        return GNUNET_SYSERR;
      }
      break;
    }
    case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_DATA:
    {
      if (recv->state < GNUNET_PSYC_MESSAGE_STATE_METHOD
          || recv->mod_value_size_expected != recv->mod_value_size)
      {
        LOG (GNUNET_ERROR_TYPE_WARNING,
             "Dropping out of order message data fragment "
             "(%u < %u || %lu != %lu).\n",
             recv->state, GNUNET_PSYC_MESSAGE_STATE_METHOD,
             recv->mod_value_size_expected, recv->mod_value_size);

        GNUNET_break_op (0);
        recv_error (recv);
        return GNUNET_SYSERR;
      }
      recv->state = GNUNET_PSYC_MESSAGE_STATE_DATA;
      break;
    }
    }

    if (NULL != recv->message_part_cb)
      recv->message_part_cb (recv->cb_cls, &recv->slave_key,
                             recv->message_id, recv->flags,
                             0, // FIXME: data_offset
                             pmsg);

    switch (ptype)
    {
    case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_END:
    case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_CANCEL:
      GNUNET_PSYC_receive_reset (recv);
      break;
    }
  }

  if (NULL != recv->message_cb)
    recv->message_cb (recv->cb_cls, message_id, flags, msg);
  return GNUNET_OK;
}