레이블이 프로토콜인 게시물을 표시합니다. 모든 게시물 표시
레이블이 프로토콜인 게시물을 표시합니다. 모든 게시물 표시

2009년 1월 5일 월요일

MySQL통신프로토콜 - 인증시의 패킷5

Error Packet
Error Packet이라는 것은 처리가 실패했다라는 것을 서버에서 클라이언트에 통지하는 것이다. 
인증시 실패했을 경우 이외에 SQL구문에러가 된 경우에도 송신된다. 
에러 코드, SQL State코드, 에러 메세지가 포함되어 있다. 

클라이언트는 패킷헤더의 뒤쪽 선두 1바이트가 0xff인지 아닌지 확인하는 것으로 Error Packet인지 판단가능하다. 

Error Packet
패킷헤더 : 4바이트
필드수  : 1바이트 , oxff로 고정
MySQL에러코드: 2바이트,  MySQL고유의 에러코드, 16진수표기
sql state marker: 1바이트, 항상 0x23(#)
sqlstate의 값: 5바이트, 문자열표기(1자리당 1바이트에 대응)
에러메세지: n바이트, 에러메세지본체.  0x00로 끝나지 않음(패킷헤더가 있기 때문에 사이즈확인가능)
  ex>Access denied for user 'user1'@'localhost' (using password: YES)
  41 63 63 65 73 73 20 
  64 65 6e 69 65 64 20 
  66 6f 72 20 
  75 73 65 72 20
  27 75 73 65 72 31 27 
  40 27 6c 6f 63 61 6c 68 6f 73 74 27 20
  28 75 73 69 6e 67 20
  70 61 73 73 77 6f 72 64 3a 20
  59 45 53 29 


  
  
  





2008년 12월 28일 일요일

MySQL통신프로토콜 - 인증시의 패킷3

Client Authentication Packet
Client Authentication Packet에서는 클라이언트에서 서버로 유저명, 패스워드등의 인증정보를 통지한다. 

client flags는 클라이언트측에서 이용가능한 옵션을 통지한다. 
max packet size는 클라이언트⇔ 서버사이에서 주고 받는 패키의 최대크기를 통지한다. 
LONGTEXT형등의 큰 데이터를 주고 받기위해서이고  패킷헤더에서 관리하고 있는 3바이트제한(16MB)하고는 관계가 없다. 
큰 데이터를 주고 받기 위해서 필요한 경우에는 mysql의 접속 파라메터인 max_allowed_packet에 큰 수치를 설정하는 것이 정석이다.  이 부분에 반영된다. 

charset number는 클라이언트 측의 캐릭터셋을 서버에 통지한다. 
명령어 라인 툴인 mysql 디폴트에서는 0x08(latin1)이 된다. 
다만 Connector/J 라든지 skip-character-set-client-handshake을 지정한 상태로 mysqld를 기동한 경우에는 서버의 캐릭터셋에 맞추어지므로 Handshake Initialization Packet에서 보내지는 서버의 캐릭터셋하고 같은 번호가 세팅된다. 

계속해서 사용자명, 암호화된 패스워드, 초기 데이터베이스명(지정한 경우만)이 송신된다. 
유저명과 데이터베이스명은 「Null Terminated String」,패스워드는 「Length Coded String」표기가 된다. 
Null Terminated String이라는 것은 문장열 종단에 0x00(null)로 표시하는 것이다. 
문자열 자신에 null문자가 포함되는 경우는 사용할 수 없지만 유저명, 데이터베이스명에서는 그것이 쓰여질 이유가 없기 때문에 문제없다.  한편 Length Coded String은 선두 1바이트(또는 복수 바이트)로 문자열의 크기를 선언해 놓는 것이다. 이것은 Null Terminated String하고는 달리 예를 들어 null문자를 포함한 바이트열이 있어서 처리할 수 있게 된다. 

Client Authentication Packet
패킷헤더 4바이트
client_flags 4바이트 , 클라이언트에서 이용가능한 옵션
max_packet_size 4바이트
charset number 1바이트
filler 23바이트  ,   예약영역, 현재는 항상 0x00
유저명 n+1바이트, 유저명, 최후는 0x00.  따라서 유저명의 바이트수를 n바이트라고 하면 n+1이 된다. 
패스워드의 scramble크기 1바이트,  패스워드의 scramble크기를 16진수표기로 저장. 현재는 0x14(20)고정. 패스워드가 없는 경우에는 0x00고정
패스워드의 scramble  20바이트  패스워드의 암호화를 위한 문자열, 패스워드가 없는 경우에는 사용되지 않음. 
데이터베이스명 n+1 데이터베이스명. 최후에는 0x00.  데이터베이스명을 지정하지 않는 경우에는 사용되지 않음. 





2008년 12월 21일 일요일

MySQL통신프로토콜 - 인증시의 패킷1

인증시의 패킷
인증시에는  다음과 같은 패킷을 주고 받는다. 

클라이언트                                                                서버
       ---------TCP또는 소켓통신------------------>
      <-------①Handshake Initialization Packet-----
       --------②Client Authentication Packet ------>
     <--------③Ok Packet 또는  ④Error Packet ----

※패킷헤더 
처음, 패킷헤더에 대해서 설명해 본다. 
패킷헤더라는 것은 모든 패킷의 선두에 할당되는 영역으로 4바이트로 구성된다. 
선두3바이트가 패킷의 길이(패킷헤더 길이는 빼고), 1바이트가 패킷의 연번이다. 
예를들어 Handshake Initialization Packet에서는 ox41 00 00 =65(10진수)이면 Handshake Initialization Packet의 총 바이트수가 65바이트라는 것을 의미한다. 
패킷의 내용은 전부 16진수로 표기한다. 

이 패킷길이처럼 수치를 16진수로 표현하는 게 있으면 문자열을 16진수로 표현하는 것이 있다. 
수치표현의 경우에는 전부 little endian이다. 
패킷번호는 00으로 시작해서 왔다갔다 할때마다 1개씩 증가한다. 
새로운 명령이 되면 또 00부터 번호가 할당된다.  클라이언트에서 1패킷보내면 서버에서 복수의 패킷이 되돌아오는 것도 있기 때문에 (검색할 때등) 그럴 때 사용하는 연번이다. 

3바이트는 24비트이기 때문에 다룰 수 있는 수치의 최대값은 16,777,215바이트(약 16MB)가 된다.  LONGTEXT형등의 거대한 필드에서는 열 크기가 이것을 넘는 경우도 있지만 그럴 때에는 다음처럼 2개이상의 패킷에 걸쳐서 송수신된다. 

FF FF FF 00 ...
FF FF FF 01 ...
13 01 00 02 ... 

패킷의 크기가 「0xFF FF FF」의 경우에는 그 패킷이 16MB이상의 되기 때문에 1패킷으로는 완결되지 못하고 후속의 패킷에 계속됨을 알려주고 있다.  이  경우에는 1개의 논리 패킷이 3개의 물리적인 패킷에 걸쳐져 있게 된다.