QNX RTOS: 5-3. Client Information Structure

2025. 12. 2. 16:33운영체제/QNX

1. Client Information Structure 개요

  • 문제의식
    • 서버 입장: “지금 나한테 MsgSend()한 클라이언트가 누구인지 / 어떤 버퍼 크기를 가지고 있는지 / 어떤 권한을 가진 프로세스인지 알고 싶다.”
  • 어디서 정보를 얻는가?
    • MsgReceive()의 4번째 인자에 _msg_info 구조체 포인터를 넘기면,
      → 커널이 메시지 수신과 동시에 클라이언트 정보를 채워줌.
    • 지금까지는 주로 NULL 로 넘겼는데,
      이 자리에 _msg_info를 넘기면 클라이언트 정보까지 같이 얻는 것.
struct _msg_info info;
rcvid = MsgReceive(chid, &msg, sizeof(msg), &info);

 

  • 중요:
    • 메시지에 대해서만 info가 업데이트됨.
    • Pulse에 대해서는 info가 갱신되지 않음 → 이전 값이나 쓰레기값일 수 있음.

2. _msg_info에 들어있는 정보들

_msg_info는 “클라이언트에 대한 메타데이터”를 담는 구조체:

 

  • 프로세스/스레드 정보
    • pid : MsgSend()를 호출한 클라이언트 프로세스 ID
    • tid : MsgSend()를 호출한 클라이언트 스레드 ID
  • 연결/채널 정보
    • chid : 서버의 채널 ID
    • coid : 클라이언트 입장에서는 “내가 서버에 붙어 있는 Connection ID”
    • scoid: 서버가 클라이언트를 식별하기 위한 Connection ID (Server Connection ID)
      → 서버 내부에서 “이 클라이언트 핸들”처럼 쓰는 ID
  • 우선순위 및 플래그
    • priority : 해당 메시지를 보낸 클라이언트 스레드의 우선순위
      → 서버 스레드는 일반적으로 이 priority로 동작 (QNX의 IPC 특징)
    • flags : 메시지/연결과 관련된 여러 플래그
  • 메시지 길이 정보
    • msglen (source message length)
      • 클라이언트가 보낸 메시지의 실제 길이
    • dstmsglen (destination message length)
      • 클라이언트가 reply를 받을 때 사용할 버퍼의 크기
  • 이 길이 정보를 통해:
    • 커널은 “둘 중 더 작은 길이만큼만” 복사
      • send 시: min(보낸 길이, 서버 수신 버퍼 길이)
      • reply 시: min(서버가 보내려는 길이, 클라이언트 reply 버퍼 길이)
    • 서버는 dstmsglen을 보고:
      • “클라이언트가 reply를 최대 몇 바이트까지 받을 수 있는지” 를 알 수 있음.

 


3. scoid(Server Connection ID)의 의미와 사용

3.1 scoid란?

  • 서버 입장에서:
    • 이 클라이언트 연결을 가리키는 인덱스/핸들” 같은 것
    • internal connection table에서 해당 클라이언트 데이터를 찾을 때 키로 쓰기 좋음.

3.2 활용 예시

  • 리소스 테이블 관리
    • 서버가 scoid를 key로 해서
      • 각 클라이언트별 상태, open된 리소스 정보, 통계 등을 저장
    • 클라이언트가 종료되거나 disconnect 되면:
      • 해당 scoid에 대응되는 구조체/리소스를 정리(cleanup)
  • 인증/접근 제어
    • 서버가 “누가 나에게 메세지를 보냈는가?”를 scoid 기준으로 관리
    • 특정 클라이언트만 허용하거나,
      블랙리스트/화이트리스트 관리에 사용할 수 있음.

4. ConnectClientInfo() – 추가 정보를 알고 싶을 때

  • _msg_info로도 충분한 정보가 있지만,
    서버가 더 많은 인증 정보를 원할 수 있음:
    • 예: “이 클라이언트의 UID/GID가 무엇인지, 어떤 능력/권한이 있는지 알고 싶다”
  • 이때 사용하는 함수가 ConnectClientInfo():
struct _client_info ci;
ConnectClientInfo(NULL, info.scoid, &ci, 0);
 
  • 여기서 얻을 수 있는 정보:
    • uid, gid
    • supplemental group, capabilities(ability)
    • 기타 보안 관련 정보
  • 활용:
    • 특정 UID만 허용
    • 특정 group에 속한 프로세스만 접속 허용 등
    • “권한이 없는 클라이언트의 요청은 MsgError()로 거절” 같은 정책 구현

5. _msg_info의 실전 활용 포인트

5.1 데이터 검증 & Reply 공간 검증

  • 데이터 검증
    • 요청 메시지 헤더에 “이만큼의 데이터를 달라”고 적혀 있지만,
    • 실제 클라이언트의 send 길이/버퍼가 이상할 수 있음.
    • _msg_info의 msglen을 보고:
      • “클라이언트가 실제로 얼마나 보내왔는지”를 확인
      • 범위를 넘어선 요청을 방어 (out-of-bounds 방지)
  • reply 공간 체크
    • 서버가 많은 데이터를 보내고 싶을 때:
      • _msg_info.dstmsglen으로
        • “클라이언트 reply 버퍼 크기” 확인
      • 그 크기를 넘지 않도록 잘라서 보내거나,
        • 부족하면 에러/부분전송 처리

5.2 로깅 및 디버깅

  • _msg_info의 pid, tid를 이용해서:
    • “어떤 프로세스/스레드가 어떤 요청을 보냈는지” 로그에 남김
    • 장애 상황/성능 분석 시 매우 유용:
      • 예: 특정 PID가 비정상적으로 많은 요청을 보낸다
  • 실시간/안전 시스템에서:
    • “특정 클라이언트의 과도한 요청 → 서버 응답 지연” 같은 이슈 추적에 도움

6. 정리

  • MsgReceive()의 4번째 인자(기존에 NULL로 두던 것)는
    클라이언트 메타데이터를 담는 _msg_info 구조체 주소를 넘기는 자리.
  • 이 구조체를 통해:
    1. 누가 보냈는지 (PID/TID, scoid, priority)
    2. 얼마나 보냈고, 얼마나 돌려줄 수 있는지 (msglen, dstmsglen)
    3. 추가 인증 정보로 연결할 수 있는 키(scoid) 를 얻을 수 있음.
  • Pulse는 이 구조가 업데이트되지 않는다는 점이 중요 포인트.
  • 이후에 ConnectClientInfo()와 연계하면
    IPC + 보안/인증 + 로깅까지 통합된 서버 설계가 가능해짐.

'운영체제 > QNX' 카테고리의 다른 글

QNX RTOS: 5-5. Multi-Part Messages  (0) 2025.12.02
QNX RTOS: 5-4. How a Client Finds a Server  (0) 2025.12.02
QNX RTOS: 5-2. Pulses  (0) 2025.12.02
QNX RTOS: 5-1. Message Passing  (0) 2025.11.27
QNX RTOS: 5. Interprocess Communication  (0) 2025.11.27