%%Title: talk(1) を探る

%%Created: Sat Feb 23 00:11:49 JST 2002
%%Updated: Tue Mar  5 16:16:47 JST 2002

talk を IPv6 対応するにあたって、ちょろっと talk を調べた。

o talkとは?

何なのかは man talk するとして、基本的な仕組みは、

	- 発側Aのユーザが talk(1)を起動すると呼側Bの talkd(8)を呼出す。
	  この時はUDPを使う。
	  と同時に、Aの talkd(8)を応答待ち状態にする。
	- B の talkd(8)はユーザの端末へ呼出があったことを通知する。
	- 呼出を受けたユーザは talk(1)を起動して、Aのtalkd(8)へ Aの
	  応答待ちポート番号を教えてもらう。
	- B の talk(1)は Aの talk(1) に繋ぎにいく。
	  この時はTCPを使う。

o talk のパケットフォーマット

draft-hunter-talk-00.txt によると talk のパケットには2種類ある。
1つは要求メッセージ(request message)、もう1つは応答メッセージ(response message)。

要求メッセージのフォーマットは

         0                   1                   2                   3
         0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |     vers      |     type      |              pad              |
        +---------------+---------------+-------------------------------+
        |                            id_num                             |
        +---------------------------------------------------------------+
        |                                                               |
        |                     address (osockaddr)                       |
        |                                                               |
        |                                                               |
        +---------------------------------------------------------------+
        |                                                               |
        |                   control_addr (osockaddr)                    |
        |                                                               |
        |                                                               |
        +---------------------------------------------------------------+
        |                              pid                              |
        +---------------------------------------------------------------+
        |                                                               |
        |                   caller's name (12 bytes)                    |
        |                                                               |
        +---------------------------------------------------------------+
        |                                                               |
        |                   callee's name (12 bytes)                    |
        |                                                               |
        +---------------------------------------------------------------+
        |                                                               |
        |                    callee's TTY (16 bytes)                    |
        |                                                               |
        |                                                               |
        +---------------------------------------------------------------+

応答メッセージは

         0                   1                   2                   3
         0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |     vers      |     type      |    answer     |      pad      |
        +---------------+---------------+---------------+---------------+
        |                            id_num                             |
        +---------------------------------------------------------------+
        |                                                               |
        |                     data_addr (osockaddr)                     |
        |                                                               |
        |                                                               |
        +---------------------------------------------------------------+

osockaddr は以下の様に定義されている。

       0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |            family             |             port              |
      +-------------------------------+-------------------------------+
      |                          IP address                           |
      +---------------------------------------------------------------+
      |                              pad                              |
      +---------------------------------------------------------------+
      |                              pad                              |
      +---------------------------------------------------------------+

なんとアドレス部分は 4バイトに定義されている。padを使っても12バイト。
これはIPv6と相性が悪い。

o 現状の talk(1)/talkd(8) on BSD variants の動作

draft-hunter-talk-00.txt はパケットフォーマットとメッセージタイプしか
記述してないので、実際の動作とコードを追いかけてみる。

	talk(1) は caller (callee)
	talkd(8) は caller's (callee's) daemon

	- caller sends LOOK_UP message to callee's daemon.

		id = 0
		addr = null
		udp addr/port
		caller's name
		callee's name
		callee's tty

	+ callee's daemon looks for a LEAVE_INVITE entry in the controll table
	  by both caller's name and callee's name. 
	  if callee's daemon finds the entry.
	  callee's daemon sends a response with SUCCESS.

		id = table's value
		callee's tcp addr/port

	  if not find, callee's daemon sends a response with NOT_HERE.

		id = 0

	- if caller receives a SUCCESS.
	  then caller connects to callee's tcp port.

	  if caller receives a NOT_HERE.
	  then caller sends ANNOUNCE to callee's daemon.

		id = -1
		tcp addr/port
		udp addr/port
		caller's name
		callee's name
		callee's tty

	+ callee's daemon checks if there is a entry which has same callee's
	  name and tty.  if there is not, callee's damon replys with an error.
	  callee's daemon checks if there is a entry which has same callee's
	  name, tty and pid.  if there is not, callee's daemon inserts new
	  entry to the controll table, and callee's daemon announces to the
	  user.  if there is, callee's daemon updates id_num and also announces
	  to the user.  in both case, callee's daemon sends a SUCCESS.
	  
		id = callee's id

	- if caller receives a SUCCESS.
	  caller sends LEAVE_INVITE to caller's daemon.

		id = callee's id
		tcp addr/port
		udp addr/port
		caller's name
		callee's name
		callee's tty

	+ caller's daemon checks if there is a entry which has same callee's
	  name, tty and pid.  if there is not, caller's damon inserts new
	  entry to the controll table.  if there is, caller's daemon updates
	  id_num.  in both case, caller's daemon sends a SUCCESS.

		id = caller's id

	- if caller receives a SUCCESS.  caller waits until callee connects.
	  if callee connects to caller's tcp addr/port.
	  caller sends DELETE to caller's (and callee's) daemon.

		id = caller's id (or callee's id)
		tcp addr/port
		udp addr/port
		caller's name
		callee's name
		callee's tty

よって、udp addr/port は必要ない。tcp addr も必要ない気がするが、
明示的に指定して接続させたいこともあるだろうから残しとく。

その他メモ
	ある人につなぎに行こうとした時に、既に別な人からの呼出があった場合
	そっちにつながってしまう。

	kterm(1) をインストールした時に sビットがないと utmp(5) を書き換えない。
	talkd(8) は utmp(5) を検査してユーザがログインしているかどうかを調べる。