Exemplo n.º 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;
}
Exemplo n.º 2
0
int receiver_recv(struct receiver *recvr,
		  const struct sa *src, struct mbuf *mb)
{
	struct hdr hdr;
	uint64_t now = tmr_jiffies();
	size_t start, sz;
	int err;

	if (!recvr || !mb)
		return EINVAL;

	if (!recvr->ts_start)
		recvr->ts_start = now;
	recvr->ts_last = now;

	start = mb->pos;
	sz = mbuf_get_left(mb);

	/* decode packet */
	err = protocol_decode(&hdr, mb);
	if (err) {
		if (err == EBADMSG) {
			re_fprintf(stderr, "[%u] ignore a non-Turnperf packet"
				   " from %J (%zu bytes)\n",
				   recvr->allocid, src, sz);
			hexdump(stderr, mb->buf + start, sz);
			return 0;
		}

		re_fprintf(stderr, "receiver: protocol decode"
			   " error [%zu bytes from %J] (%m)\n", sz, src, err);
		re_fprintf(stderr, "          %w\n", mb->buf + start, sz);
		return err;
	}

	/* verify packet */
	if (hdr.session_cookie != recvr->cookie) {
		re_fprintf(stderr, "invalid cookie received"
			   " from %J [exp=%x, actual=%x] (%zu bytes)\n",
			   src, recvr->cookie, hdr.session_cookie, sz);
		protocol_packet_dump(&hdr);
		return EPROTO;
	}
	if (hdr.alloc_id != recvr->allocid) {
		re_fprintf(stderr, "invalid allocation-ID received"
			   " from %J [exp=%u, actual=%u] (%zu bytes)\n",
			   src, hdr.alloc_id, recvr->allocid, sz);
		protocol_packet_dump(&hdr);
		return EPROTO;
	}

	if (recvr->last_seq) {
		if (hdr.seq <= recvr->last_seq) {
			re_fprintf(stderr, "receiver[%u]: late or "
				   " out-of-order packet from %J"
				   " (last_seq=%u, seq=%u)\n",
				   recvr->allocid, src,
				   recvr->last_seq, hdr.seq);
		}
	}

#if 0
	protocol_packet_dump(&hdr);
#endif

	recvr->total_bytes   += sz;
	recvr->total_packets += 1;

	recvr->last_seq = hdr.seq;

	return 0;
}