Beispiel #1
0
bool server_start(int port)
{
    bool success =
        _create_socket(port) &&
        _bind_to_socket(port) &&
        _listen_on_socket();

    if (!success){
        _close_socket();
        return false;
    }

    log_trace("Accepting connections on port %d", port);
    while(success){
        int acceptedfd;
        success = _accept_on_socket(&acceptedfd);
        if (success){
            session_start(acceptedfd);
        }
        else{
            break;
        }
    }
    log_print(LOG_INFO, "Stopped accepting connections on port %d", port);
    _close_socket();
    return true;
}
Beispiel #2
0
static int
_connect_to_server(lcm_tcpq_t *self)
{
    fprintf(stderr, "LCM tcpq: connecting...\n");

    if(self->socket)
        _close_socket(self->socket);

    self->socket=socket(AF_INET,SOCK_STREAM,0);
    if(self->socket < 0) {
        perror("lcm_tcpq socket");
        return -1;
    }

    struct sockaddr_in sa;
    sa.sin_family = AF_INET;
    sa.sin_port=self->server_port;
    sa.sin_addr=self->server_addr;

    if(0 != connect(self->socket, (struct sockaddr *)&sa, sizeof(sa))) {
        perror("lcm_tcpq connect");
        goto fail;
    }

    if(_send_uint32(self->socket, MAGIC_CLIENT) ||
       _send_uint32(self->socket, PROTOCOL_VERSION)) {
        goto fail;
    }

    uint32_t server_magic;
    uint32_t server_version;
    if(_recv_uint32(self->socket, &server_magic) ||
       _recv_uint32(self->socket, &server_version)) {
        goto fail;
    }

    if(server_magic != MAGIC_SERVER) {
        fprintf(stderr, "LCM tcpq: Invalid response from server\n");
        goto fail;
    }

    for(GSList* elem=self->subs; elem; elem=elem->next) {
        gchar* channel = (char*)elem->data;
        if(0 != _sub_unsub_helper(self, channel, MESSAGE_TYPE_SUBSCRIBE))
        {
            fprintf(stderr, "LCM tcpq: error while subscribing to %s\n", channel);
            goto fail;
        }
    }

    dbg(DBG_LCM, "LCM tcpq: connected (%d)\n", self->socket);
    return 0;

fail:
        fprintf(stderr, "LCM tcpq: Unable to connect to server\n");
        _close_socket(self->socket);
        self->socket = -1;
        return -1;
}
Beispiel #3
0
static int
lcm_tcpq_publish(lcm_tcpq_t *self, const char *channel, const void *data,
        unsigned int datalen)
{
    if(self->socket < 0 && 0 != _connect_to_server(self)) {
            return -1;
    }

    uint32_t channel_len = strlen(channel);

    if(_send_uint32(self->socket, MESSAGE_TYPE_PUBLISH) ||
       _send_uint32(self->socket, channel_len) ||
       (channel_len != _send_fully(self->socket, channel, channel_len)) ||
       _send_uint32(self->socket, datalen) ||
       (datalen != _send_fully(self->socket, data, datalen)))
    {
        perror("LCM tcpq send");
        dbg(DBG_LCM, "Disconnected!\n");
        _close_socket(self->socket);
        self->socket = -1;
        return -1;
    }

    return 0;
}
Beispiel #4
0
void server_stop()
{
    log_print(LOG_INFO, "Initiating shutdown...");
    _is_shutting_down = true;
    _close_socket();
    session_end_all();
}
Beispiel #5
0
static void
lcm_tcpq_destroy (lcm_tcpq_t *self)
{
    g_slist_free(self->subs);
    if(self->socket >= 0)
        _close_socket(self->socket);
    if(self->server_addr_str)
        g_free(self->server_addr_str);
    free(self->recv_channel_buf);
    free(self->data_buf);
    free(self);
}
Beispiel #6
0
static int
lcm_tcpq_handle(lcm_tcpq_t * self)
{
    if(self->socket < 0 && 0 != _connect_to_server(self)) {
        return -1;
    }

    // read, ignore message type
    uint32_t msg_type;
    if(_recv_uint32(self->socket, &msg_type))
        goto disconnected;

    // read channel length, channel
    uint32_t channel_len;
    if(_recv_uint32(self->socket, &channel_len))
        goto disconnected;
    if(_ensure_buf_capacity((void**)&self->recv_channel_buf,
                &self->recv_channel_buf_len, channel_len+1)) {
        fprintf(stderr, "Memory allocation error\n");
        return -1;
    }
    if(channel_len != _recv_fully(self->socket, self->recv_channel_buf,
                channel_len))
        goto disconnected;
    self->recv_channel_buf[channel_len] = 0;

    // read payload size, payload
    uint32_t data_len;
    if(_recv_uint32(self->socket, &data_len))
        goto disconnected;
    if(_ensure_buf_capacity(&self->data_buf, &self->data_buf_len, data_len)) {
        fprintf(stderr, "Memory allocation error\n");
        return -1;
    }
    if(data_len != _recv_fully(self->socket, self->data_buf, data_len))
        goto disconnected;

    lcm_recv_buf_t rbuf;
    rbuf.data = self->data_buf;
    rbuf.data_size = data_len;
    rbuf.recv_utime = timestamp_now();
    rbuf.lcm = self->lcm;

    if(lcm_try_enqueue_message(self->lcm, self->recv_channel_buf))
        lcm_dispatch_handlers(self->lcm, &rbuf, self->recv_channel_buf);
    return 0;

disconnected:
    _close_socket(self->socket);
    self->socket = -1;
    return -1;
}
Beispiel #7
0
void
lcm_udpm_destroy (lcm_udpm_t *lcm) 
{
    dbg (DBG_LCM, "closing lcm context\n");
    _destroy_recv_parts (lcm);

    if (lcm->sendfd >= 0)
        _close_socket(lcm->sendfd);

    lcm_internal_pipe_close(lcm->notify_pipe[0]);
    lcm_internal_pipe_close(lcm->notify_pipe[1]);

    g_static_rec_mutex_free (&lcm->mutex);
    g_static_mutex_free (&lcm->transmit_lock);
    free (lcm);
}
Beispiel #8
0
static void
_destroy_recv_parts (lcm_udpm_t *lcm)
{
    if (lcm->thread_created) {
        // send the read thread an exit command
        int wstatus = lcm_internal_pipe_write(lcm->thread_msg_pipe[1], "\0", 1);
        if(wstatus < 0) {
            perror(__FILE__ " write(destroy)");
        } else {
            g_thread_join (lcm->read_thread);
        }
        lcm->read_thread = NULL;
        lcm->thread_created = 0;
    }

    if (lcm->thread_msg_pipe[0] >= 0) {
        lcm_internal_pipe_close(lcm->thread_msg_pipe[0]);
        lcm_internal_pipe_close(lcm->thread_msg_pipe[1]);
        lcm->thread_msg_pipe[0] = lcm->thread_msg_pipe[1] = -1;
    }

    if (lcm->recvfd >= 0) {
        _close_socket(lcm->recvfd);
        lcm->recvfd = -1;
    }

    if (lcm->frag_bufs) {
        g_hash_table_destroy (lcm->frag_bufs);
        lcm->frag_bufs = NULL;
    }

    if (lcm->inbufs_empty) {
        lcm_buf_queue_free (lcm->inbufs_empty);
        lcm->inbufs_empty = NULL;
    }
    if (lcm->inbufs_filled) {
        lcm_buf_queue_free (lcm->inbufs_filled);
        lcm->inbufs_filled = NULL;
    }
    if (lcm->ringbuf) {
        lcm_ringbuf_free (lcm->ringbuf);
        lcm->ringbuf = NULL;
    }
}
//	Function responsible of closing an existing socket.
bool	NetworkOperator::close_socket( const unsigned int socket_id )
{
	bool	return_value = false;



	_lock.acquire_shared();

	if ( _initialised )
	{
		_socket_lock.acquire();
		return_value = _close_socket(socket_id);
		_socket_lock.release();
	}

	_lock.release_shared();


	return return_value;
};
Beispiel #10
0
static int
_sub_unsub_helper(lcm_tcpq_t *self, const char *channel, uint32_t msg_type)
{
    if(self->socket < 0) {
        fprintf(stderr, "LCM not connected (%d)\n", self->socket);
        return -1;
    }

    uint32_t channel_len = strlen(channel);
    if(_send_uint32(self->socket, msg_type) ||
       _send_uint32(self->socket, channel_len) ||
       (channel_len != _send_fully(self->socket, channel, channel_len)))
    {
        perror("LCM tcpq");
        dbg(DBG_LCM, "Disconnected!\n");
        _close_socket(self->socket);
        self->socket = -1;
        return -1;
    }

    return 0;
}
Beispiel #11
0
static void do_cleanup(struct cleanup_node_struct **head_ref) {
    struct cleanup_node_struct *current = (*head_ref);
    struct cleanup_node_struct *previous = NULL, *gone = NULL;

    while (current != NULL) {
        if (ssh_channel_is_closed(current->data->channel)) {
            if (current == (*head_ref)) {
                (*head_ref) = current->next;
            }
            if (previous != NULL) {
                previous->next = current->next;
            }
            gone = current;
            current = current->next;

            if (gone->data->channel) {
                _close_socket(*gone->data);
                ssh_remove_channel_callbacks(gone->data->channel, gone->data->cb_chan);
                ssh_channel_free(gone->data->channel);
                gone->data->channel = NULL;

                SAFE_FREE(gone->data->p_fd);
                SAFE_FREE(gone->data->cb_chan);
                SAFE_FREE(gone->data);
                SAFE_FREE(gone);
            }
            else {
                fprintf(stderr, "channel already freed!\n");
            }
            _ssh_log(SSH_LOG_FUNCTIONS, "=== do_cleanup", "Freed.");
        }
        else {
            ssh_channel_close(current->data->channel);
            previous = current;
            current = current->next;
        }
    }
}
//	Function responsible of performing the operations of the class.
void	NetworkOperator::_operate()
{
	std::vector<unsigned int>		pending_close_sockets(0,NULL);
	unsigned int					buffer_size_to_use = sizeof(DawnEngine::Network::Message);
	char							buffer[sizeof(DawnEngine::Network::Message)];
	DawnEngine::Network::Message	message;
	
	#ifndef	NETWORK_OPERATOR_NO_LOGGING

		DawnEngine::IO::LogManagerA*	log_manager_a = DawnEngine::IO::LogManagerA::get();
		DawnEngine::IO::LogManagerW*	log_manager_w = DawnEngine::IO::LogManagerW::get();

	#endif	/* NETWORK_OPERATOR_NO_LOGGING */

	unsigned int					counter = 0;



	_socket_lock.acquire_shared();
	counter = 0;

	while ( counter < _pending_connection_sockets.size() )
	{
		if ( _pending_connection_sockets[counter] > 0 )
		{
			std::map<unsigned int,SocketStatus>::iterator	socket_iterator(_sockets.find(_pending_connection_sockets[counter]));



			if ( socket_iterator != _sockets.end()  &&  socket_iterator->second.first != NULL  &&  !socket_iterator->second.second )
			{
				if ( socket_iterator->second.first->connect() )
				{
					std::deque<unsigned int>::iterator	pending_socket_iterator(_pending_connection_sockets.begin() + counter);



					if ( pending_socket_iterator != _pending_connection_sockets.end() )
					{
						#ifndef	NETWORK_OPERATOR_NO_LOGGING

							if ( log_manager_a != NULL )
								log_manager_a->log_message("TCP Socket with ID %u connected to %s:%u",_pending_connection_sockets[counter],socket_iterator->second.first->address().c_str(),socket_iterator->second.first->port());

							if ( log_manager_w != NULL )
								log_manager_w->log_message(L"TCP Socket with ID %u connected.",_pending_connection_sockets[counter]);

						#endif	/* NETWORK_OPERATOR_NO_LOGGING */

						_pending_connection_sockets.erase(pending_socket_iterator);
						socket_iterator->second.second = true;
					}
				}
				else
				{
					std::deque<unsigned int>::iterator	pending_socket_iterator(_pending_connection_sockets.begin() + counter);
					int									error_code = socket_iterator->second.first->last_error();
					bool								remove = false;



					if ( error_code != WSAEWOULDBLOCK  &&  error_code != WSAECONNREFUSED  &&  error_code != WSAEISCONN  &&  error_code != WSAEALREADY )
					{
						#ifndef	NETWORK_OPERATOR_NO_LOGGING

							if ( log_manager_a )
								log_manager_a->log_error("TCP Socket with ID %u connect error with code %i.",_pending_connection_sockets[counter],error_code);

							if ( log_manager_w )
								log_manager_w->log_error(L"TCP Socket with ID %u connect error with code %i.",_pending_connection_sockets[counter],error_code);

						#endif	/* NETWORK_OPERATOR_NO_LOGGING */
									
						remove = true;
					}
					else if ( error_code == WSAEISCONN )
					{
						#ifndef	NETWORK_OPERATOR_NO_LOGGING

							if ( log_manager_a != NULL )
								log_manager_a->log_message("TCP Socket with ID %u connected to %s:%u",_pending_connection_sockets[counter],socket_iterator->second.first->address().c_str(),socket_iterator->second.first->port());

							if ( log_manager_w != NULL )
								log_manager_w->log_message(L"TCP Socket with ID %u connected.",_pending_connection_sockets[counter]);

						#endif	/* NETWORK_OPERATOR_NO_LOGGING */
							
						socket_iterator->second.second = true;
						remove = true;
					}
					else
						++counter;

					if ( remove  &&  pending_socket_iterator != _pending_connection_sockets.end() )
						_pending_connection_sockets.erase(pending_socket_iterator);
				}
			}
			else
			{
				std::deque<unsigned int>::iterator	pending_socket_iterator(_pending_connection_sockets.begin() + counter);



				if ( pending_socket_iterator != _pending_connection_sockets.end() )
					_pending_connection_sockets.erase(pending_socket_iterator);
			}
		}
		else
		{
			std::deque<unsigned int>::iterator	pending_socket_iterator(_pending_connection_sockets.begin() + counter);



			if ( pending_socket_iterator != _pending_connection_sockets.end() )
				_pending_connection_sockets.erase(pending_socket_iterator);
		}
	}

	_send_lock.acquire();
	counter = 0;
	
	while ( counter < _send_queue.size() )
	{
		bool	remove = false;



		if ( _send_queue[counter].first > 0 )
		{
			std::vector<unsigned int>::iterator				pending_close_iterator = pending_close_sockets.begin();
			std::map<unsigned int,SocketStatus>::iterator	socket_iterator(_sockets.find(_send_queue[counter].first));
			bool											found = false;



			while ( !found  &&  pending_close_iterator != pending_close_sockets.end() )
			{
				if ( (*pending_close_iterator) == _send_queue[counter].first )
					found = true;
				else
					++pending_close_iterator;
			}

			if ( !found  &&  socket_iterator != _sockets.end() )
			{
				if ( socket_iterator->first != NULL )
				{
					if ( socket_iterator->second.second )
					{
						unsigned long	remaining_bytes = buffer_size_to_use;
						int				exit_code = 0;
						char*			temp_buffer = buffer;
			


						memset(buffer,'\0',buffer_size_to_use);
						memcpy(buffer,&(_send_queue[counter].second),buffer_size_to_use);

						while ( exit_code != ERROR_CODE  &&  remaining_bytes > 0 )
						{
							exit_code = socket_iterator->second.first->send(temp_buffer,remaining_bytes,NULL);

							if ( exit_code == ERROR_CODE )
							{
								int	error_code = socket_iterator->second.first->last_error();



								if ( error_code != WSAEWOULDBLOCK  &&  error_code != WSAETIMEDOUT )
								{
									#ifndef	NETWORK_OPERATOR_NO_LOGGING

										if ( log_manager_a != NULL )
											log_manager_a->log_error("Send on socket with ID %u failed with error %u. Socket will be closed.",_send_queue[counter].first,error_code);

										if ( log_manager_w != NULL )
											log_manager_w->log_error(L"Send on socket with ID %u failed with error %u. Socket will be closed.",_send_queue[counter].first,error_code);

									#endif	/* NETWORK_OPERATOR_NO_LOGGING */

									pending_close_sockets.push_back(_send_queue[counter].first);
								}
							}
							else
							{
								remaining_bytes -= std::min(remaining_bytes,static_cast<unsigned long>(exit_code));
								temp_buffer += exit_code;
							}
						}

						remove = true;
					}
				}
				else
					remove = true;
			}
			else
				remove = true;
		}
		else
		{
			for ( std::map<unsigned int,SocketStatus>::iterator socket_iterator = _sockets.begin();  socket_iterator != _sockets.end();  ++socket_iterator )
			{
				std::vector<unsigned int>::iterator	pending_close_iterator = pending_close_sockets.begin();
				bool								found = false;



				while ( !found  &&  pending_close_iterator != pending_close_sockets.end() )
				{
					if ( (*pending_close_iterator) == socket_iterator->first )
						found = true;
					else
						++pending_close_iterator;
				}

				if ( !found  &&  socket_iterator->second.second  &&  socket_iterator->second.first != NULL )
				{
					unsigned long	remaining_bytes = buffer_size_to_use;
					int				exit_code = 0;
					char*			temp_buffer = buffer;
			


					memset(buffer,'\0',buffer_size_to_use);
					memcpy(buffer,&(_send_queue[counter].second),buffer_size_to_use);

					while ( exit_code != ERROR_CODE  &&  remaining_bytes > 0 )
					{
						exit_code = socket_iterator->second.first->send(temp_buffer,remaining_bytes,NULL);

						if ( exit_code == ERROR_CODE )
						{
							int	error_code = socket_iterator->second.first->last_error();



							if ( error_code != WSAEWOULDBLOCK  &&  error_code != WSAETIMEDOUT )
							{
								#ifndef	NETWORK_OPERATOR_NO_LOGGING

									if ( log_manager_a != NULL )
										log_manager_a->log_error("Send on socket with ID %u failed with error %u. Socket will be closed.",socket_iterator->first,error_code);

									if ( log_manager_w != NULL )
										log_manager_w->log_error(L"Send on socket with ID %u failed  with error %u. Socket will be closed.",socket_iterator->first,error_code);

								#endif	/* NETWORK_OPERATOR_NO_LOGGING */

								pending_close_sockets.push_back(socket_iterator->first);
							}
						}
						else
						{
							remaining_bytes -= std::min(remaining_bytes,static_cast<unsigned long>(exit_code));
							temp_buffer += exit_code;

							if ( exit_code == 0 )
							{
								exit_code = ERROR_CODE;
								pending_close_sockets.push_back(socket_iterator->first);
							}
						}
					}
				}
			}

			remove = true;
		}

		if ( remove )
		{
			std::deque<SocketMessage>::iterator	message_iterator(_send_queue.begin() + counter);



			if ( message_iterator != _send_queue.end() )
				_send_queue.erase(message_iterator);
			else
				++counter;
		}
		else
			++counter;
	}

	_send_lock.release();
	_receive_lock.acquire();

	for ( std::map<unsigned int,SocketStatus>::iterator socket_iterator = _sockets.begin();  socket_iterator != _sockets.end();  ++socket_iterator )
	{
		std::vector<unsigned int>::iterator	pending_close_iterator = pending_close_sockets.begin();
		bool								found = false;



		while ( !found  &&  pending_close_iterator != pending_close_sockets.end() )
		{
			if ( (*pending_close_iterator) == socket_iterator->first )
				found = true;
			else
				++pending_close_iterator;
		}

		if ( !found  &&  socket_iterator->second.second  &&  socket_iterator->second.first != NULL )
		{
			unsigned long	remaining_bytes = buffer_size_to_use;
			int				exit_code = 0;
			char*			temp_buffer = buffer;
			bool			closed = false;



			while ( exit_code != ERROR_CODE )
			{
				memset(buffer,'\0',buffer_size_to_use);
				temp_buffer = buffer;
				remaining_bytes = buffer_size_to_use;
				exit_code = 0;			

				while ( exit_code != ERROR_CODE  &&  remaining_bytes > 0 )
				{
					exit_code = socket_iterator->second.first->receive(buffer,remaining_bytes,NULL);

					if ( exit_code == ERROR_CODE )
					{
						int	error_code = socket_iterator->second.first->last_error();



						if ( error_code != WSAEWOULDBLOCK  &&  error_code != WSAETIMEDOUT )
						{
							#ifndef	NETWORK_OPERATOR_NO_LOGGING

								if ( log_manager_a )
									log_manager_a->log_error("Receive on socket with ID %u failed. Socket will be closed.",socket_iterator->first);

								if ( log_manager_w != NULL )
									log_manager_w->log_error(L"Receive on socket with ID %u failed. Socket will be closed.",socket_iterator->first);

							#endif	/* NETWORK_OPERATOR_NO_LOGGING */

							closed = true;
						}
					}
					else
					{
						remaining_bytes -= std::min(remaining_bytes,static_cast<unsigned long>(exit_code));
						temp_buffer += exit_code;

						if ( exit_code == 0 )
						{
							DawnEngine::Network::SocketProtocol	type = socket_iterator->second.first->protocol();



							if ( type == DawnEngine::Network::SOCKET_TCP_V4  ||  type == DawnEngine::Network::SOCKET_TCP_V6 )
							{
								exit_code = ERROR_CODE;
								closed = true;
							}
							else
								exit_code = ERROR_CODE;
						}
					}
				}

				if ( remaining_bytes == 0 )
				{
					memset(&message,'\0',buffer_size_to_use);
					memcpy(&message,buffer,buffer_size_to_use);
					_receive_queue.push_back(SocketMessage(socket_iterator->first,message));
				}
				else if ( closed )
				{
					memset(&message,'\0',buffer_size_to_use);
					message.message_code = ERROR_CODE;
					_receive_queue.push_back(SocketMessage(socket_iterator->first,message));
					pending_close_sockets.push_back(socket_iterator->first);
				}
			}
		}
	}

	_receive_lock.release();

	for ( std::vector<unsigned int>::iterator socket_iterator = pending_close_sockets.begin();  socket_iterator != pending_close_sockets.end();  ++socket_iterator )
		_close_socket((*socket_iterator));

	pending_close_sockets.clear();
	_socket_lock.release_shared();
};
Beispiel #13
0
static SOCKET _connect_to_host(int plain, const char *address) {
  SOCKET fd;
  struct sockaddr_in inaddr;
#ifndef WIN32
  struct sockaddr_un unaddr;
#endif
  char name[512];
  int unixsockets;
  unsigned short port;
  struct hostent *hent = NULL;
  struct protoent *prstruc = NULL;

  if ( ! sockets_initialized ) initialize_sockets(NULL,NULL,NULL,NULL);

#ifdef WIN32
  unixsockets = parse_address(address,name,&port,NULL,0);
  if ( unixsockets ) {
    warn("Unix sockets not supported on Windows");
    return INVALID_SOCKET;
  }
#else
  unixsockets = parse_address(address,name,&port,unaddr.sun_path,sizeof(unaddr.sun_path));
#endif /* WIN32 */

  if ( !unixsockets ) {
    hent = gethostbyname(name);
    
    if ( ! hent ) {
      perror("connect_to_host: gethostbyname failed");
      return INVALID_SOCKET;
    }
    
    prstruc = getprotobyname("tcp");
    if ( prstruc == NULL ) {
      perror("connect_to_host: getprotobyname failed");
      return INVALID_SOCKET;
    }
  }

  fd = socket(unixsockets ? AF_UNIX : AF_INET,
	      SOCK_STREAM,
	      unixsockets ? 0 : prstruc->p_proto);
  if ( fd == INVALID_SOCKET ) {
    perror("connect_to_host: socket failed");
    return INVALID_SOCKET;
  }

#ifndef WIN32
  if ( unixsockets ) {
    unaddr.sun_family = AF_UNIX;
    if ( connect(fd,(struct sockaddr *)&unaddr,sizeof(struct sockaddr_un)) < 0 ) {
      perror("connect_to_host: connect failed");
      return INVALID_SOCKET;
    }
  } else {
#else
  if ( 1 ) {
#endif /* WIN32 */
    inaddr.sin_family = AF_INET;
    inaddr.sin_port = htons(port);
    inaddr.sin_addr = *((struct in_addr *)hent->h_addr);
    if ( connect(fd,(struct sockaddr *)&inaddr,sizeof(struct sockaddr_in)) < 0 ) {
      perror("connect_to_host: connect failed");
      return INVALID_SOCKET;
    }
  }
  
#ifndef WIN32
  /* mark close on exec */
  fcntl(fd,F_SETFD,1);
#endif /* WIN32 */

  /* Set a five-minute keepalive in order to dissuade natting routers
     from dropping the connection */
  { int data = 1;
    int n;
    n = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&data, sizeof(int));
    if ( n < 0 ) {
      perror("connect_to_host: setsockopt keepalive failed");
    } else {
#ifdef TCP_KEEPIDLE
      /* this call exists on modern Linuxes, but not everywhere */
      data = 300;
      n = setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &data, sizeof(int));
      if ( n < 0 ) {
	/* of course, this is not supported for unix sockets. We could
	   have checked the address family, but it's probably simpler
	   just to ignore errors */
	if ( errno != ENOTSUP ) {
	  perror("connect_to_host: setsockopt keepidle failed");
	}
      }
#endif
    }
  }

  if ( !plain && skt_open_transform ) {
    return (SOCKET) skt_open_transform(fd);
  } else {
    return fd;
  }
}

SOCKET connect_to_host(const char *address) {
  return _connect_to_host(0,address);
}

SOCKET plain_connect_to_host(const char *address) {
  return _connect_to_host(1,address);
}


/* close a network connection */
static int _close_socket(int plain, SOCKET s) {
  if ( !plain && skt_closer ) {
    return skt_closer((void *)s);
  } else {
    return closesocket(s);
  }
}

int close_socket(SOCKET s) {
  return _close_socket(0,s);
}

int plain_close_socket(SOCKET s) {
  return _close_socket(1,s);
}

/* read a line, up to lf/crlf terminator, from the socket,
   and return it.
   Internal backslashes are removed, unless doubled.
   If the line ends with an unescaped backslash, replace by newline,
   and append the next line.
   If there is an error or end of file before seeing a terminator,
   NULL is returned. At present, error includes reading a partial line.
   The returned string is valid until the next call of get_line.
   This is the internal function implementing the next two;
   the second arg says whether the first is int or SOCKET.
*/
static char *_get_line(SOCKET fd,int is_socket) {
  int length,i,j;
  int offset=0;
  static char *buffer = NULL;
  static size_t buffer_size = 0;

  while ( 1 ) {
    while ( 1 ) {
      while (offset+1 >= (int)buffer_size) { /* +1 to keep some space for '\0' */
	buffer_size = (buffer_size == 0) ? 1024 : (2 * buffer_size);
	buffer = realloc(buffer, buffer_size);
	if (!buffer) {
	  perror("get_line");
	  exit(-1);
	}
      }
      length = (is_socket ?
	(skt_reader ? skt_reader((void *)fd,buffer+offset,1)
		  : 
#ifdef WIN32
		  recv(fd,buffer+offset,1,0)
#else
		  read(fd,buffer+offset,1)
#endif
	 ) : read(fd,buffer+offset,1));
      if ((length <= 0) || (buffer[offset] == '\n'))
	break;
      offset += length;
    }
    if ( offset == 0 ) return NULL;
    if ( length <= 0 ) {
      fprintf(stderr,"get_line read partial line");
      return NULL;
    }
    offset += length;
    buffer[offset] = '\0';
    /* now check for newline */
    if ( buffer[offset-1] == '\n' ) {
      if ( buffer[offset-2] == '\r' && buffer[offset-3] == '\\' ) {
        /* zap the CR */
	buffer[offset-2] = '\n';
	buffer[offset-1] = '\0';
	offset -= 1;
        /* and go onto next clause */
      }
      if ( buffer[offset-2] == '\\' ) {
	/* we have to decide whether this is an escaped backslash */
	int j = 1,k=offset-3;
	while ( k >= 0 && buffer[k--] == '\\' ) j++;
	if ( j & 1 ) {
	  /* odd number, not escaped */
	  buffer[offset-2] = '\n' ;
	  buffer[--offset] = '\0' ;
	  /* read another line */
	} else break; /* return this line */
      } else break; /* return this line */
    } /* no newline, keep going */
  }
  /* now remove internal backslashes */
  for ( i = j = 0; 1; i++, j++ ) {
    if ( buffer[j] == '\\' ) {
      j++;
    }
    buffer[i] = buffer[j];
    if ( !buffer[i] ) break;
  }
  return buffer;
}
Beispiel #14
0
void syscall_handler()
{
	static int free_vm_proc;        
	int syscall_num;
	unsigned int mem_size;
	struct t_process_context* current_process_context;
	struct t_processor_reg processor_reg;
	int* params;
	char data;
	unsigned int on_exit_action;

 	SAVE_PROCESSOR_REG
	//call can come from kernel mode (sleep)
	SWITCH_DS_TO_KERNEL_MODE
	on_exit_action=0;
	current_process_context=system.process_info->current_process->val;
	t_console_desc *console_desc=current_process_context->console_desc;
	syscall_num=processor_reg.eax;
	params=processor_reg.ecx;
	if (syscall_num==1) 
	{
		params[0]=_fork(processor_reg);
	}
	else if (syscall_num==2)
	{ 
		params[1]=_malloc(params[0]);
	}
	else if (syscall_num==3)
	{ 
		_free(params[0]);
	}
	else if (syscall_num==150)
	{ 
		params[1]=_bigMalloc(params[0]);
	}
	else if (syscall_num==151)
	{ 
		_bigFree(params[0]);
	}
	else if (syscall_num==4)
	{ 
		_write_char(console_desc,params[0]);
	}
	else if (syscall_num==5)
	{ 
		data=_read_char(console_desc);
		*((char*)params[0])=data;	
		if (data==NULL)
		{
			on_exit_action=1; 
		}
	}
	else if (syscall_num==6)
	{ 
		_echo_char(console_desc,params[0]);
	}
	else if (syscall_num==7)
	{ 
		_enable_cursor(console_desc);	
	}
	else if (syscall_num==8)
	{ 
		_disable_cursor(console_desc);
	}
	else if (syscall_num==9)
	{ 
		_update_cursor(console_desc);	
	}
	else if (syscall_num==10)
	{
		_delete_char(console_desc);
	}
	else if (syscall_num==11)
	{
		_pause();	
		on_exit_action=1; 
	}
	else if (syscall_num==12)
	{
		_awake(params[0]);
	}
	else if (syscall_num==13)
	{
		_exit(params[0]);
		on_exit_action=2;
	}
	else if (syscall_num==14) 
	{
		params[2]=_exec(params[0],params[1]); 
	}
	else if (syscall_num==15) 
	{
		_sleep_time(params[0]);	
		on_exit_action=1; 
	}
	else if (syscall_num==18) 
	{
		params[2]=_open(system.root_fs,(char*) params[0],params[1]); 
		on_exit_action=1; 
	}

	else if (syscall_num==19) 
	{
		params[1]=_close(system.root_fs,params[0]);
		on_exit_action=1; 
	}

	else if (syscall_num==20) 
	{
		params[3]=_read(system.root_fs,params[0],params[1],params[2]); 
		on_exit_action=1; 
	}

	else if (syscall_num==21) 
	{
		params[3]=_write(system.root_fs,(void*)params[0],params[1],params[2]);
		on_exit_action=1;  
	}
	
	else if (syscall_num==22)
	{
		params[1]=_rm(system.root_fs,(char*)params[0]);
		on_exit_action=1; 
	}

	else if (syscall_num==23) 
	{
		params[1]=_mkdir(system.root_fs,params[0]);
		on_exit_action=1; 
	}
	//syscall 24 and 25 test only
	else if (syscall_num==24) 
	{
		t_io_request* io_request;
		io_request=kmalloc(sizeof(t_io_request));
		io_request->device_desc=system.device_desc;
		io_request->sector_count=params[0];
		io_request->lba=params[1];
		io_request->io_buffer=params[2];
		io_request->process_context=current_process_context;
		_read_28_ata(io_request);
		kfree(io_request);
	}
	else if (syscall_num==25) 
	{
		t_io_request* io_request;
		io_request=kmalloc(sizeof(t_io_request));
		io_request->device_desc=system.device_desc;
		io_request->sector_count=params[0];
		io_request->lba=params[1];
		io_request->io_buffer=params[2];
		io_request->process_context=current_process_context;
		_write_28_ata(io_request);
		kfree(io_request);
	}
	else if (syscall_num==26) 
	{
		params[1]=_chdir(system.root_fs,(char*) params[0]); 
		on_exit_action=1; 	
	}
	else if (syscall_num==27)
	{
		params[2]=_stat(system.root_fs,(char*) params[0],params[1]); 	
	}

	else if (syscall_num==28)
	{
 		params[1]=_open_socket(system.network_desc->socket_desc,params[0]); 
	}
	else if (syscall_num==29)
	{
 		params[3]=_bind(system.network_desc->socket_desc,params[0],params[1],params[2]);
	}
	else if (syscall_num==30)
	{
 		params[5]=_recvfrom(system.network_desc->socket_desc,params[0],params[1],params[2],params[3],params[4]);
	}
	else if (syscall_num==31)
	{
 		params[5]=_sendto(system.network_desc->socket_desc,params[0],params[1],params[2],params[3],params[4]);
	}
	else if (syscall_num==32)
	{
 		params[1]=_close_socket(system.network_desc->socket_desc,params[0]);
	}

	else if (syscall_num==101) 
	{
		on_exit_action=1; 
	}
	else if (syscall_num==102) 
	{
		_flush_ata_pending_request();
	}
	//DEBUG WRAPPER
	else if (syscall_num==103)
	{
		check_free_mem();
	}
	else if (syscall_num==104)
	{
		debug_network(params[0],params[1]);
	}
	else
	{
		panic();
	}
//	EXIT_INT_HANDLER(on_exit_action,processor_reg)

	static struct t_process_context _current_process_context;                                          
	static struct t_process_context _old_process_context;                                              
	static struct t_process_context _new_process_context;	                                            
	static struct t_processor_reg _processor_reg;                                                       
	static unsigned int _action;
//	static short _ds;                                                                        
                                                                                                            
	CLI
//	_ds=ds;                                                                         
	_action=on_exit_action;                                                                                
	_current_process_context=*(struct t_process_context*)system.process_info->current_process->val;                                  
	_old_process_context=_current_process_context;                                                      
	_processor_reg=processor_reg;                                                           
	if (_action>0)                                                                                      
	{                                                                                   
		schedule(&_current_process_context,&_processor_reg);                            
		_new_process_context=*(struct t_process_context*)(system.process_info->current_process->val);
		_processor_reg=_new_process_context.processor_reg;                          
		SWITCH_PAGE_DIR(FROM_VIRT_TO_PHY(((unsigned int) _new_process_context.page_dir)))                                                          
		DO_STACK_FRAME(_processor_reg.esp-8);

//		unsigned int* xxx;
//		unsigned int* yyy;
//		unsigned int* zzz;
//		xxx=FROM_PHY_TO_VIRT(((unsigned int*)_new_process_context.page_dir)[0]) & 0xFFFFF000;
//		zzz=FROM_PHY_TO_VIRT(xxx[256]);
	
		if (_action==2)                                                                              
		{                                                                           
			DO_STACK_FRAME(_processor_reg.esp-8);                                               
//			free_vm_process(_old_process_context.page_dir,INIT_VM_USERSPACE);
			free_vm_process(&_old_process_context);
//			if (_old_process_context.phy_add_space!=NULL)
//			{ 
//				buddy_free_page(&system.buddy_desc,FROM_PHY_TO_VIRT(_old_process_context.phy_add_space));
//				buddy_free_page(system.buddy_desc,FROM_PHY_TO_VIRT(_old_process_context.phy_user_stack));
//			}
			buddy_free_page(system.buddy_desc,FROM_PHY_TO_VIRT(_old_process_context.phy_kernel_stack)); 	                                  
		}                                                                             
		RESTORE_PROCESSOR_REG                                
		EXIT_SYSCALL_HANDLER                                                        
	}                                                                                                   
Beispiel #15
0
lcm_provider_t * 
lcm_udpm_create (lcm_t * parent, const char *network, const GHashTable *args)
{
    udpm_params_t params;
    memset (&params, 0, sizeof (udpm_params_t));

    g_hash_table_foreach ((GHashTable*) args, new_argument, &params);

    if (parse_mc_addr_and_port (network, &params) < 0) {
        return NULL;
    }

    lcm_udpm_t * lcm = (lcm_udpm_t *) calloc (1, sizeof (lcm_udpm_t));

    lcm->lcm = parent;
    lcm->params = params;
    lcm->recvfd = -1;
    lcm->sendfd = -1;
    lcm->thread_msg_pipe[0] = lcm->thread_msg_pipe[1] = -1;
    lcm->udp_low_watermark = 1.0;

    lcm->kernel_rbuf_sz = 0;
    lcm->warned_about_small_kernel_buf = 0;

    lcm->frag_bufs = g_hash_table_new_full (_sockaddr_in_hash, 
            _sockaddr_in_equal, NULL, (GDestroyNotify) lcm_frag_buf_destroy);
    lcm->frag_bufs_total_size = 0;
    lcm->frag_bufs_max_total_size = 1 << 24; // 16 megabytes
    lcm->max_n_frag_bufs = 1000;

    if(0 != lcm_internal_pipe_create(lcm->notify_pipe)) {
        perror(__FILE__ " pipe(create)");
        g_hash_table_destroy(lcm->frag_bufs);
        free(lcm);
        return NULL;
    }
    fcntl (lcm->notify_pipe[1], F_SETFL, O_NONBLOCK);

    g_static_rec_mutex_init (&lcm->mutex);
    g_static_mutex_init (&lcm->transmit_lock);

    dbg (DBG_LCM, "Initializing LCM UDPM context...\n");
    dbg (DBG_LCM, "Multicast %s:%d\n", inet_ntoa(params.mc_addr), ntohs (params.mc_port));

    // setup destination multicast address
    memset (&lcm->dest_addr, 0, sizeof (lcm->dest_addr));
    lcm->dest_addr.sin_family = AF_INET;
    lcm->dest_addr.sin_addr = params.mc_addr;
    lcm->dest_addr.sin_port = params.mc_port;

    // test connectivity
    SOCKET testfd = socket (AF_INET, SOCK_DGRAM, 0);
    if (connect (testfd, (struct sockaddr*) &lcm->dest_addr, 
                sizeof (lcm->dest_addr)) < 0) {

        perror ("connect");
        lcm_udpm_destroy (lcm);
#ifdef __linux__
        linux_check_routing_table(lcm->dest_addr.sin_addr);
#endif
        return NULL;
    }
    _close_socket(testfd);

    // create a transmit socket
    //
    // don't use connect() on the actual transmit socket, because linux then
    // has problems multicasting to localhost
    lcm->sendfd = socket (AF_INET, SOCK_DGRAM, 0);

    // set multicast TTL
    if (params.mc_ttl == 0) {
        dbg (DBG_LCM, "LCM multicast TTL set to 0.  Packets will not "
                "leave localhost\n");
    }
    dbg (DBG_LCM, "LCM: setting multicast packet TTL to %d\n", params.mc_ttl);
    if (setsockopt (lcm->sendfd, IPPROTO_IP, IP_MULTICAST_TTL,
                (char *) &params.mc_ttl, sizeof (params.mc_ttl)) < 0) {
        perror ("setsockopt(IPPROTO_IP, IP_MULTICAST_TTL)");
        lcm_udpm_destroy (lcm);
        return NULL;
    }

#ifdef WIN32
    // Windows has small (8k) buffer by default
    // increase the send buffer to a reasonable amount.
    int send_buf_size = 256 * 1024;
    setsockopt(lcm->sendfd, SOL_SOCKET, SO_SNDBUF, 
            (char*)&send_buf_size, sizeof(send_buf_size));
#endif

    // debugging... how big is the send buffer?
    int sockbufsize = 0;
    unsigned int retsize = sizeof(int);
    getsockopt(lcm->sendfd, SOL_SOCKET, SO_SNDBUF, 
            (char*)&sockbufsize, (socklen_t *) &retsize);
    dbg (DBG_LCM, "LCM: send buffer is %d bytes\n", sockbufsize);

    // set loopback option on the send socket
#ifdef __sun__
    unsigned char send_lo_opt = 1;
#else
    unsigned int send_lo_opt = 1;
#endif
    if (setsockopt (lcm->sendfd, IPPROTO_IP, IP_MULTICAST_LOOP, 
                (char *) &send_lo_opt, sizeof (send_lo_opt)) < 0) {
        perror ("setsockopt (IPPROTO_IP, IP_MULTICAST_LOOP)");
        lcm_udpm_destroy (lcm);
        return NULL;
    }

    // don't start the receive thread yet.  Only allocate resources for
    // receiving messages when a subscription is made.

    return lcm;
}