Commit 8783b155 authored by Seblu's avatar Seblu
Browse files

Derniere version sll

parent 9d5f9a22
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -540,7 +540,7 @@ void Screen::cmd_exec(const char *s) {
  // String is a remote command
  else {
    if (C.connected()) {
      C.sendln(s, strlen(s));
      C.sendln(s);
      S << ">> " << s << "\n";
    }
    else S << "Unable to send: " << s << ". Try to reconnect with /login !\n";
+63 −70
Original line number Diff line number Diff line
@@ -51,7 +51,13 @@ Connection::Connection(int fd) : socket_fd_(fd), local_port_(-1), remote_port_(-

  if (socket_fd_ >= 0) {
    id_ = getconnid();
    setconninfo_();
    try {
      setlocalip_();
      setlocalport_();
      setremoteip_();
      setremoteport_();
    }
    catch (...) { }
  }
}

@@ -87,24 +93,6 @@ void Connection::disconnect() {
  pthread_mutex_unlock(&c_mutex_);
}

/**
 * Return the connection sate
 * Cannot be const, du to mutex locking
 *
 * @return see description
 */
bool Connection::connected() {
  // get connection mutex

  pthread_mutex_lock(&c_mutex_);

  bool ret = (socket_fd_ >= 0);

  pthread_mutex_unlock(&c_mutex_);

  return ret;
}

/**
 * Create connection with @param addr on port @param port
 */
@@ -156,15 +144,27 @@ void Connection::connect(const char *addr, int port) {

  // connect
  if (::connect(socket_fd_, (struct sockaddr *) &daddr, sizeof daddr) == -1) {
    int errno__ = errno;
    disconnect_();
    pthread_mutex_unlock(&w_mutex_);
    pthread_mutex_unlock(&r_mutex_);
    pthread_mutex_unlock(&c_mutex_);
    throw Error(ERR_NET, (string) "Unable to connect to " + addr  + ": " + hstrerror(h_errno));
    throw Error(ERR_NET, (string) "Unable to connect to " + addr  + ": " + strerror(errno__));
  }

  // set infos
  setconninfo_();
  try {
    setlocalip_();
    setlocalport_();
    setremoteip_();
    setremoteport_();
  }
  catch (...) {
    pthread_mutex_unlock(&w_mutex_);
    pthread_mutex_unlock(&r_mutex_);
    pthread_mutex_unlock(&c_mutex_);
    throw;
  }

  pthread_mutex_unlock(&w_mutex_);
  pthread_mutex_unlock(&r_mutex_);
@@ -229,7 +229,16 @@ void Connection::listen(int port, int max) {
  }

  // set all infos
  setconninfo_();
  try {
    setlocalip_();
    setlocalport_();
  }
  catch (...) {
    pthread_mutex_unlock(&w_mutex_);
    pthread_mutex_unlock(&r_mutex_);
    pthread_mutex_unlock(&c_mutex_);
    throw;
  }

  pthread_mutex_unlock(&w_mutex_);
  pthread_mutex_unlock(&r_mutex_);
@@ -274,72 +283,59 @@ Connection *Connection::accept() {
 * Send data on @param buf of size @param len on socket
 */
void Connection::send(const char* buf, size_t len) {
  // keep the socket fd
  // lock mutex for operation
  pthread_mutex_lock(&c_mutex_);
  pthread_mutex_lock(&w_mutex_);

  // retreive socket_fd and free conn mutex
  int socket_fd = socket_fd_;
  pthread_mutex_unlock(&c_mutex_);

  // test socket validity
  if (socket_fd < 0)
  if (socket_fd < 0) {
    pthread_mutex_unlock(&w_mutex_);
    throw Error(ERR_NET, "No connection established but trying to send data");
  }

  // send is a write operation
  pthread_mutex_lock(&w_mutex_);
  int ret = ::send(socket_fd_, buf, len, 0);
  pthread_mutex_unlock(&w_mutex_);
  int ret = ::send(socket_fd_, buf, len, MSG_NOSIGNAL);

  if (ret == -1 && errno == ECONNRESET)
    throw Error(ERR_NET, "Connection reset by peer");
  if (ret == -1)
    throw Error(ERR_NET, "send: " + (string) strerror(errno));
}

/**
 * Send data on @param buf of size @param len followed by '\n' on socket
 */
void Connection::sendln(const char* buf, size_t len) {
  // keep the socket fd
  // treat error
  if (ret == -1) {
    int errno__ = errno;
    pthread_mutex_lock(&c_mutex_);
  int socket_fd = socket_fd_;
    pthread_mutex_lock(&r_mutex_);
    disconnect_();
    pthread_mutex_unlock(&r_mutex_);
    pthread_mutex_unlock(&c_mutex_);

  // test socket validity
  if (socket_fd < 0)
    throw Error(ERR_NET, "No connection established but trying to send line");

  // send is a write op
  pthread_mutex_lock(&w_mutex_);
  // write data
  int ret = ::send(socket_fd, buf, len, 0);
  if (ret == -1) {
    pthread_mutex_unlock(&w_mutex_);
    if (errno == ECONNRESET)
    pthread_mutex_unlock(&r_mutex_);
    if (errno__ == ECONNRESET || errno__ == EPIPE)
      throw Error(ERR_NET, "Connection reset by peer");
    throw Error(ERR_NET, "sendln: " + (string) strerror(errno));
    else
      throw Error(ERR_NET, "send: " + (string) strerror(errno__));
  }

  // write '\n'
  ret = ::send(socket_fd, "\n", 1, 0);
  // release the mutex
  pthread_mutex_unlock(&w_mutex_);
  if (ret == -1)
    throw Error(ERR_NET, "sendln: " + (string) strerror(errno));
}

/**
 * Receive a line
 */
string Connection::recvln() {
  // keep the socket fd
  // lock mutex for operation
  pthread_mutex_lock(&c_mutex_);
  pthread_mutex_lock(&r_mutex_);

  int socket_fd = socket_fd_;
  pthread_mutex_unlock(&c_mutex_);

  // test socket validity
  if (socket_fd < 0)
  if (socket_fd < 0) {
    pthread_mutex_unlock(&r_mutex_);
    throw Error(ERR_NET, "No connection established but trying to receive line");
  }

  // recv is a read opearation
  pthread_mutex_lock(&r_mutex_);
  do {
    // check EOL char
    size_t offset = rbuf_.find('\n');
@@ -354,25 +350,22 @@ string Connection::recvln() {
    static char local_buf[MAX_LINE_SIZE];
    int ret = ::recv(socket_fd, local_buf, MAX_LINE_SIZE, 0);

    if (ret == 0) {
    if (ret == -1 || ret == 0) {
      pthread_mutex_lock(&c_mutex_);
      pthread_mutex_lock(&w_mutex_);
      disconnect_();
      pthread_mutex_unlock(&r_mutex_);
      pthread_mutex_unlock(&c_mutex_);
      pthread_mutex_unlock(&r_mutex_);
      throw Error(ERR_NET, "Connection reset by peer");
    }

    if (ret == -1) {
      *local_buf = 0;

      // unlock before error
      pthread_mutex_unlock(&r_mutex_);

      if (ret == 0)
	throw Error(ERR_NET, "Connection reset by peer");
      else
	throw Error(ERR_NET, (string) "recvln: " + strerror(errno));
    }
    else local_buf[ret] = 0;
    local_buf[ret] = 0;

    // add read data in buffer
    rbuf_ += local_buf;
+2 −4
Original line number Diff line number Diff line
@@ -35,15 +35,14 @@ public:
  void listen(int port, int max);

  void disconnect();
  bool connected();
  inline bool connected();

  Connection *accept();

  // send methods
  inline void send(const string &data);
  void send(const char* buf, size_t len);
  inline void send(const string &data);
  inline void sendln(const string &data);
  void sendln(const char* buf, size_t len);

  // recv methods
  string recvln();
@@ -64,7 +63,6 @@ protected:
  inline void socket_();
  inline void disconnect_();

  inline void setconninfo_();
  inline void setlocalip_();
  inline void setlocalport_();
  inline void setremoteip_();
+29 −17
Original line number Diff line number Diff line
@@ -27,6 +27,24 @@
 ** Public method
 ******************************************************************************/

/**
 * Return the connection sate
 * Cannot be const, du to mutex locking
 *
 * @return see description
 */
bool Connection::connected() {
  // get connection mutex

  pthread_mutex_lock(&c_mutex_);

  bool ret = (socket_fd_ >= 0);

  pthread_mutex_unlock(&c_mutex_);

  return ret;
}

/**
 * Send @param data on socket
 */
@@ -38,30 +56,20 @@ void Connection::send(const string &data) {
 * Send @param data followed by '\n' on socket
 */
void Connection::sendln(const string &data) {
  sendln(data.c_str(), data.length());
  string tosend = data + "\n";
  send(tosend.c_str(), tosend.length());
}

/*******************************************************************************
 ** Protected method
 ******************************************************************************/

/**
 * Set all information about a connection
 */
void Connection::setconninfo_() {
  setlocalip_();
  setlocalport_();
  setremoteip_();
  setremoteport_();
}

/**
 * Free a socket
 * No mutex used !
 */
void Connection::disconnect_() {
  if (socket_fd_ == -1)
    return;
  assert(socket_fd_ >= 0);

  close(socket_fd_);
  socket_fd_ = -1;
@@ -90,7 +98,8 @@ void Connection::setlocalip_() {
  struct sockaddr_in addr;
  socklen_t len = sizeof addr;

  ::getsockname(socket_fd_, (struct sockaddr*) &addr, &len);
  if (::getsockname(socket_fd_, (struct sockaddr*) &addr, &len) != 0)
    throw Error(ERR_NET, (string) "Unable to set local ip: " + strerror(errno));
  local_ip_ = inet_ntoa(addr.sin_addr);
}

@@ -102,7 +111,8 @@ void Connection::setlocalport_() {
  struct sockaddr_in addr;
  socklen_t len = sizeof addr;

  ::getsockname(socket_fd_, (struct sockaddr*) &addr, &len);
  if (::getsockname(socket_fd_, (struct sockaddr*) &addr, &len) != 0)
    throw Error(ERR_NET, (string) "Unable to set local port: " + strerror(errno));
  local_port_ = ntohs(addr.sin_port);
}

@@ -114,7 +124,8 @@ void Connection::setremoteip_() {
  struct sockaddr_in addr;
  socklen_t len = sizeof addr;

  ::getpeername(socket_fd_, (struct sockaddr*) &addr, &len);
  if (::getpeername(socket_fd_, (struct sockaddr*) &addr, &len) != 0)
    throw Error(ERR_NET, (string) "Unable to set remote ip: " + strerror(errno));
  remote_ip_ = inet_ntoa(addr.sin_addr);
}

@@ -126,6 +137,7 @@ void Connection::setremoteport_() {
  struct sockaddr_in addr;
  socklen_t len = sizeof addr;

  ::getpeername(socket_fd_, (struct sockaddr*) &addr, &len);
  if (::getpeername(socket_fd_, (struct sockaddr*) &addr, &len) != 0)
    throw Error(ERR_NET, (string) "Unable to set remote port: " + strerror(errno));
  remote_port_ = ntohs(addr.sin_port);
}