Exemple #1
0
void *_handle_peer_interconnect(void *arg) {
  assert(arg != NULL);

  LOG("[%d] 收到 rpc 客户端连接\n", self_index);

  st_netfd_t client = (st_netfd_t)arg;
  arg = NULL;

  // 握手
  // rpc客户端连入后,会主动发来客户端自己的 index
  // 长度为 1 字节
  char    buf[4096];
  ssize_t  len;

  // 先只读取 1 字节的客户端握手头,表示客户端自己的 index
  if ((len = st_read(client, buf, 1, ST_UTIME_NO_TIMEOUT)) < 0) {
    ERR("[%d] failed to handshake from client #%d: %s\n", self_index, *buf, strerror(errno));
    goto close_fd_and_quit;
  } else if (len == 0) {
    goto close_fd_and_quit;
  }

  uint8_t   client_index = (uint8_t)buf[0];

  LOG("[%d] 来自 rpc 客户端 #%d 的握手已经成功建立\n", self_index, client_index);

  // 如果 client_index 等于自己的 self_index,则这个有问题
  if (client_index == self_index) {
    ERR("[%d] rpc client promet the same index with mine.\n", self_index);
    goto close_fd_and_quit;
  }

  // 将客户端 fd 放入属于它 index 的 fd_list 内
  // 在前面的 make link to peers 当中,已经把写去远程结点的 st_netfd_t 保存于 fd_list 之内了
  // 所以不需要需要将远程连入的 st_netfd_t 保存在自己的 fd_list
  /*if (fd_list[client_index] != NULL) {
    ERR("[%d] This client #%d has connected before, replace it.\n", self_index, client_index);
    st_netfd_close(fd_list[client_index]);
  }
  fd_list[client_index] = client;*/

  // 初始化用于读取流的包结构
  struct rpc_package *package;
  package = (struct rpc_package*)calloc(1, sizeof(struct rpc_package));
  //

  const size_t pkghead_len = sizeof(rpcpkg_len);
  size_t      receive;
  size_t      cursor; // 记录数据偏移到了 buf 的什么位置

  // 循环服务处理
  for (;;) {
    if ((len = st_read(client, buf, sizeof(buf), ST_UTIME_NO_TIMEOUT)) < 0) {
      ERR("[%d] failed when read from client #%d.\n", self_index, client_index);
      goto free_package_close_fd_and_quit;
    } else if (len == 0) {
      goto free_package_close_fd_and_quit;
    } else {
      if (len > sizeof(buf))
        LOG("[%d] read %ld bytes into buffer with size: %lu bytes.\n", self_index, len, sizeof(buf));

      // 流进来数据了
      cursor = 0;
      while (cursor < len) { // 如果缓冲区内数据没有处理完

        // 如果之前没切过包,或者前一包已经完成
        if (package->total == package->received) {
          package->total = NTOH(*(rpcpkg_len *)(buf + cursor));

          if (len - cursor - pkghead_len >= package->total) {
            package->received = package->total;
          } else {
            package->received = len - cursor - pkghead_len;
          }

          memcpy(&package->data, buf + cursor + pkghead_len, package->received);

          cursor += package->received + pkghead_len;
        } else {
          // 现在处理的是断开包
          assert(package->received < package->total);

          receive = (len >= package->total - package->received) ? package->total - package->received : len;

          memcpy(&package->data + package->received, buf + cursor, receive);

          package->received += receive;
          cursor += receive;
        }

        // 如果刚刚处理过的包已经是完整包,则处决它
        if (package->received == package->total) {
          struct rpc_package_head *head = protocol_decode(package);

          switch (head->type) {
            case UNKNOW:
              break;

            case REQUEST:
              LOG("[%d] receive an rpc request with method: %s and parameter: %s\n", self_index, head->body->request.method, head->body->request.parameter);

              queue_put(queue, head);

              break;

            case RESPONSE:
              LOG("[%d] response an rpc request with result: %s\n", self_index, head->body->response.result);

              // TODO: 对 response 对象的后续处理
              protocol_package_free(head);
              head = NULL;

              break;
          }
        }
      }
    }
  }

free_package_close_fd_and_quit:
  free(package);
close_fd_and_quit:
  st_netfd_close(client);
  return 0;
}
Exemple #2
0
uint16_t ofp_header_get_xid(void* ofp_msg) {
    return NTOH(((struct ofp_header*) ofp_msg)->xid, 32);
}
Exemple #3
0
/**
 * Read and validate a Pico header from a file.
 *
 * @param pico          The Pico data structure.  This must have the file.
 * @return              True iff there was an error.
 */
static bool
read_header(PICO * pico) {
    pico->valid = false;    // Not yet valid.
    if (fseek(pico->file, 0, SEEK_SET)) {
        pico->errno = CANNOT_SEEK;
        sprintf(pico->error_text, "Unable to seek to start of file.");
        return true;
    }

    // Read and check the header.
    magic_t file_magic = 0;
    if (fread(&file_magic, 1, sizeof(magic_t), pico->file) <
            sizeof(magic_t)) {
        pico->errno = CANNOT_READ;
        sprintf(pico->error_text, "Cannot read magic number.");
        return true;
    }
    file_magic = NTOH(magic_t, file_magic);
    if (file_magic != magic) {
        pico->errno = NOT_PICO;
        sprintf(pico->error_text, "Incorrect magic number in file.");
        return true;
    }
    if (fread(&pico->major, 1, sizeof(major_t), pico->file) <
            sizeof(major_t)) {
        pico->errno = CANNOT_READ;
        sprintf(pico->error_text, "Cannot read major version number.");
        return true;
    }
    pico->major = NTOH(major_t, pico->major);
    if (pico->major != VERSION_MAJOR) {
        pico->errno = BAD_VERSION;
        sprintf(pico->error_text, "File has incompatible version %d.x.",
                pico->major);
        return true;
    }
    if (fread(&pico->minor, 1, sizeof(minor_t), pico->file) <
            sizeof(minor_t)) {
        pico->errno = CANNOT_READ;
        sprintf(pico->error_text, "Cannot read minor version number.");
        return true;
    }
    pico->minor = NTOH(minor_t, pico->minor);
    if (fread(&pico->offset, 1, sizeof(offset_t), pico->file) <
            sizeof(offset_t)) {
        pico->errno = CANNOT_READ;
        sprintf(pico->error_text, "Cannot read data offset.");
        return true;
    }
    pico->offset = NTOH(offset_t, pico->offset);
    if (fread(pico->hash, 1, HASH_LEN, pico->file) <
            HASH_LEN) {
        pico->errno = CANNOT_READ;
        sprintf(pico->error_text, "Cannot read hash.");
        return true;
    }
    pico->hash_valid = true;
    if (fread(&pico->key_length, 1, sizeof(keylen_t), pico->file) <
            sizeof(keylen_t)) {
        pico->errno = CANNOT_READ;
        sprintf(pico->error_text, "Cannot read key length.");
        return true;
    }
    pico->key_length = NTOH(keylen_t, pico->key_length);
    if (pico->key_length < 1) {
        pico->errno = KEY_ERROR;
        sprintf(pico->error_text, "Key has illegal length (0).");
        return true;
    }
    pico->key = MALLOC(uint8_t, pico->key_length);
    if (pico->key == NULL) {
        pico->errno = NO_MEMORY;
        sprintf(pico->error_text, "Cannot get memory to store key.");
        return true;
    }
    if (fread(pico->key, 1, pico->key_length, pico->file) <
            pico->key_length) {
        pico->errno = CANNOT_READ;
        sprintf(pico->error_text, "Cannot read key.");
        return true;
    }
    if (pico->offset < KEY_POS + pico->key_length) {
        pico->errno = BAD_OFFSET;
        sprintf(pico->error_text, "Offset is too small.");
        return true;
    }

    // Header has been read successfully.  Compute and save the
    // metadata length.
    pico->md_length = pico->offset - KEY_POS - pico->key_length;
    pico->errno = OK;
    pico->valid = true;     // Header is now valid.
    return false;
}
Exemple #4
0
uint16_t ofp_header_get_length(void* ofp_msg) {
    return NTOH(((struct ofp_header*) ofp_msg)->length, 16);
}
Exemple #5
0
static void *handle_clientconn(void *arg) {
  st_netfd_t client = *(st_netfd_t*)arg;
  arg = NULL;

  // 握手
  // rpc客户端连入后,会主动发来客户端自己的 index
  // 长度为 1 字节
  char    buf[4096];
  ssize_t  len;

  // 先只读取 1 字节的客户端握手头,表示客户端自己的 index
  if ((len = st_read(client, buf, 1, ST_UTIME_NO_TIMEOUT)) < 0) {
    fprintf(stderr, "[%d] failed to handshake from client #%d: %s\n", my_index, *buf, strerror(errno));
    goto close_fd_and_quit;
  } else if (len == 0) {
    goto close_fd_and_quit;
  }

  uint8_t   client_index = (uint8_t)buf[0];

  fprintf(stdout, "[%d] 来自 rpc 客户端 #%d 的握手已经成功建立\n", my_index, client_index);

  // 如果 client_index 等于自己的 my_index,则这个有问题
  if (client_index == my_index) {
    fprintf(stderr, "[%d] rpc client promet the same index with mine.\n", my_index);
    goto close_fd_and_quit;
  }

  // 将客户端 fd 放入属于它 index 的 fd_list 内
  // 在前面的 make link to peers 当中,已经把写去远程结点的 st_netfd_t 保存于 fd_list 之内了
  // 所以不需要需要将远程连入的 st_netfd_t 保存在自己的 fd_list
  /*if (fd_list[client_index] != NULL) {
    fprintf(stderr, "[%d] This client #%d has connected before, replace it.\n", my_index, client_index);
    st_netfd_close(fd_list[client_index]);
  }
  fd_list[client_index] = client;*/

  // 初始化用于读取流的包结构
  struct rpc_package package;
  memset((void*)&package, 0, sizeof(package));

  const size_t pkghead_len = sizeof(rpcpkg_len);
  size_t      receive;
  size_t      cursor; // 记录数据偏移到了 buf 的什么位置

  // 循环服务处理
  for (;;) {
    if ((len = st_read(client, buf, sizeof(buf), ST_UTIME_NO_TIMEOUT)) < 0) {
      fprintf(stderr, "[%d] failed when read from client #%d.\n", my_index, client_index);
      goto close_fd_and_quit;
    } else if (len == 0) {
      goto close_fd_and_quit;
    } else {
      if (len > sizeof(buf))
        fprintf(stdout, "[%d] read %d bytes into buffer with size: %d bytes.\n", my_index, len, sizeof(buf));

      // 流进来数据了
      cursor = 0;
      while (cursor < len) { // 如果缓冲区内数据没有处理完

        // 如果之前没切过包,或者前一包已经完成
        if (package.total == package.received) {
          package.total = NTOH(*(rpcpkg_len *)(buf + cursor));

          if (len - cursor - pkghead_len >= package.total) {
            package.received = package.total;
          } else {
            package.received = len - cursor - pkghead_len;
          }

          memcpy(&package.data, buf + cursor + pkghead_len, package.received);

          cursor += package.received + pkghead_len;
        } else {
          // 现在处理的是断开包
          assert(package.received < package.total);

          receive = (len >= package.total - package.received) ? package.total - package.received : len;

          memcpy(&package.data + package.received, buf + cursor, receive);

          package.received += receive;
          cursor += receive;
        }

        // 如果刚刚处理过的包已经是完整包,则处决它
        if (package.received == package.total) {
          fprintf(stdout, "[%d] receive an rpc request with content: %s\n", my_index, package.data);
          // TODO: 添加收到 rpc 包的业务处理
        }
      }
    }
  }

close_fd_and_quit:
  st_netfd_close(client);
  return 0;
}