正誤表

読者の方からメールでご指摘いただいたりしております。大変申し訳ありません。

・Chapter04 クライアントプログラムのレベルアップ:コネクトのタイムアウト

 P125の一番下のconnect()の応答が-1の場合、EINPROGRESS以外はエラーとしていますが、SolarisなどではEINTRも発生するようです。これもシグナル割り込みなどでエラーではないので、下記のようにif分を変更しておいた方が移植性が高くなります。

if(errno!=EINTR&&errno!=EINPROGRESS){

・Chapter09 RAWソケット受信でのIPパケットのサイズ

 P298のIPパケットの処理で、RAWソケットから受信したデータサイズからIPヘッダのサイズを引いたものがIPパケットのデータのサイズとしていますが、小さなパケットでは後ろにゴミが付くようです。実際はIPヘッダにサイズがありますので、そのサイズを使用するように変更すると確実です。

        else if(ntohs(eh.ether_type)==ETHERTYPE_IP){
                /* IPパケット */
                struct ip       ip;

                /* IPヘッダ取得 */
                memcpy(&ip,ptr,sizeof(struct ip));
                ptr+=sizeof(struct ip);
                /* len-=sizeof(struct ip); */
                len=ntohs(ip.ip_len)-sizeof(struct ip);

                if(ip.ip_p==IPPROTO_TCP){

 同様に、P318のRAWソケットでの送信クライアントのサンプルでも、IPヘッダのサイズを使用するように変更します。

        if(ntohs(eh.ether_type)==ETHERTYPE_IP){
                /* IPパケット */
                struct ip       ip;

                /* IPヘッダ取得 */
                memcpy(&ip,ptr,sizeof(struct ip));
                ptr+=sizeof(struct ip);
                /* len-=sizeof(struct ip); */
                len=ntohs(ip.ip_len)-sizeof(struct ip);

                if(ip.ip_p==IPPROTO_UDP){

・Chapter02 通信の仕組み

 P28のTCPセグメントの図で、予約が4ビット、コントロールフラグが8ビットになっていますが、実際は予約6ビット、コントロールフラグ6ビットです。表では正しく6ビットと記載されていますが、図が間違えていました。

・Chapter10 SSLプログラミング

 SSL_read()が-1をリターンしても、必ずしも致命的なエラーとは限らないということがわかりました。下記のようなラッピング関数を作ると使いやすいと思いますので、ご紹介します。サーバ側がクライアント認証を途中で開始する場合などに再認証が行われますが、その際にSSL_read()が-1を返したりします。その場合はERR_get_error()でSSL_ERROR_NONEが得られます。HTTPSでクライアント認証に対応する際には注意が必要です。

int My_SSL_read(SSL *ssl,char *ptr,int size)
{
int	ret,err;

	do{
		ret=SSL_read(ssl,ptr,size);
		if(ret==-1){
			err=ERR_get_error();
			switch (err) {
				case SSL_ERROR_NONE:
					fprintf(stderr,"SSL_ERROR_NONE\n");
					break;
				case SSL_ERROR_SYSCALL:
					if (errno){
						fprintf(stderr,"SSL_ERROR_SYSCALL: Read errno=%d\n", errno);
					}
					/* fall through */
				case SSL_ERROR_WANT_WRITE:
				case SSL_ERROR_WANT_READ:
				case SSL_ERROR_WANT_X509_LOOKUP:
				case SSL_ERROR_ZERO_RETURN:
				case SSL_ERROR_SSL:
					ERR_print_errors_fp(stderr);
					return(-1);
			}
		}
	}while(ret==-1);

	return(ret);
}

 


from 2005/9/1