68user's page 掲示板

Prev< No. 4393〜4398> Next  [最新発言に戻る] [過去ログ一覧]
No. 4393 # DNS勉強中 2005/11/14 (月) 09:44:17
to 68userさん

さっそくですが、IPv6 のアドレス省略について
双方のプログラム(resolver-1.pl, 1058.txt)に
バグがあるかも知れないのでご報告します。

一例として、 198.41.0.4 www.yahoo.co.jpと入力して、
{A, B, C, D, E, F}.DNS.jpを表示させたとき、
追加情報の F.DNS.jp の出力結果は下記のとおりになります。

resolver-1.pl
2001:2F8::100::153

私の出力結果
2001:2f8::100:0:0:0:153

ちなみにEtherealの出力結果は下記のとおりです。
2001:2f8:0:100::153

IPv6 のアドレス省略表記に関する説明を下記のサイトで拝見したのですが、
http://www.soi.wide.ad.jp/iw2001/slides/04/04-1/53.html
そこには IPv6 のアドレス表記に関して2つの原則が書かれていました。
1,【連続する】0 のブロックは省略できる。
2,省略できるのは【1ヶ所】だけ。

そして出力結果から推察するに、
resolver-1.pl では、原則の1, 2共に満たしてないように見受けられます。
perl が分からないので想像ですが、
resolver-1.pl では 0 を見つけたら即座に :: に置き換え、
何回でも省略が使用できるように組んであるのかなと思われます。

私の方では、一度省略を使用したら、二度と使えないようには組んでいるのですが、
0 は即座に :: に置き換えております。
そのため 0 を見つけたら、次の場所を見て、
・次の場所も 0 なら :: に置き換える
・次の場所が 0 で無ければ、 0 を出力する。
というコードを追加しないといけないかもしれません。

勘違いでしたらすいません。

No. 4394 # 68user 2005/11/15 (火) 01:45:04
>>4393 DNS勉強中
ありがとうございます。

とりあえず TYPE=TXT の件と IPv6 の件を bugid20・21 として登録しました。
    http://x68000.q-e-d.net/~68user/bugnote/bugindex.php?projectid=1


ちなみになぜわたしが web を更新しないのは、解説文からソースへの
リンク方法が
    http://x68000.q-e-d.net/~68user/cgi-bin/cvsweb.cgi/public_html/net/org/resolver-3.html?rev=1.11&content-type=text/x-cvsweb-markup
のように
    :preinclude 21-106
などと行番号で指定しているため、修正が非常に面倒であるからです
(まぁただの言い訳なのですが)。

+10 などの相対指定にしようかとか、
      m/bind\(/
などと文字列で引っ掛けようかとか迷いつつここまで来てしまいました。
ご指摘を頂いたことについては大変感謝しておりますが、修正が遅いのは
なにとぞご容赦ください。

No. 4395 # 68user 2005/11/15 (火) 01:55:14
>>4392 DNS勉強中
> ただし、 void class_print(int class) を用いた共用の記述の仕方が
> 分からなかったので、
> codelist_t {class, type}_list[] = { ... };をグローバル化して共用しています。
一般的には、codelist_t を扱う関数を別ソースにし、ソース先頭で
    static codelist_t class_list[] = { ... };
と配列を宣言して、conv_class()・class_print() でその配列を使用
します。static をつければ外部ソースからアクセスできないので、
隠蔽できます。

ただ、複数ファイルに分けると、ヘッダファイルが必要だったり Makefile を
書きたくなったりするので、サンプルであれば分ける必要はないかもしれません。


それはそれとして複数のソースから構成される場合に、グローバル変数の
宣言をヘッダファイルで一元管理する方法をご存知なければ、一度書いて
みるとよいでしょう。

      --- var.h ----
      #ifdef THIS_IS_MAIN
      #define GLOBAL
      #else
      #define GLOBAL extern
      #endif
      GLOBAL class_list[] = {...};
      
      --- main.c ---
      #define THIS_IS_MAIN
      #include "var.h"

      --- sub.c ---
      #include "var.h"

こんな感じです。

No. 4396 # DNS勉強中 2005/11/15 (火) 12:19:47
>>4394 68user
修正の件了解致しました。

その後修正したもの
・教えていただいた
>struct DNS_Response {
> char data[10000];
> int int_data[10000];
> int pos;
>};
の構造体を下記のような感じに少し修正し、流用しました。
/* DNSサーバへの質問 */
struct DNS_Query {
    char data[10000];
    int length;
};
/* DNSサーバからの応答 */
struct DNS_Response {
    int int_data[10000];
    int pos;
};
今まで int_data と pos の 2 つの引数を渡していたところが、
struct DNS_Response だけを渡せばよくなったので、
分かりやすくなったかなと思います。

・ linux 版の warning を解消しました。
てっきり netdb.h を include したら
sys/socket.h なども include してくれるものだと勘違いしておりました。
そのため、いままでの作ってきた他のソースでも warning がたくさん出ておりました。
大変勉強になりましたm(__)m。

・ AAAA の表示を仕様に添った形に変更しました。

そんな感じに修正を施した現状のソースをアップロードしておきます(linux版)。
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/1091.txt

後、指摘された部分で残っている修正点は
・ hoge_print 関数の書き方
・ >>4395 全般
くらいかなと思います。
直したつもりで、意図に沿っていない修正をしている箇所はあるかもしれませんが(^^;。

他には、個人的に「フラグを構成する各要素」を
resolver-1.pl のように簡単に設定出来た方が良いかなと思ってます。
私のソースでは、下記一行で設定してしまってるのがいまいちかなと。
DNS_packet->flag = 0x0100;
ビットフィールドあたりで記述してうまく動作すれば良いのですが。
もっともここ自体は今回のソースでは変更することはなさそうなので、
このままでも良いのかもと思ったりも…。

No. 4397 # DNS勉強中 2005/11/15 (火) 17:14:29
>>4395 68user
今まで一つのソースで完結するものばかり書いていたので、
static の付いたグローバル変数(内部結合グローバル変数)を
使った事はありませんでした。
大変勉強になりました。

後、グローバル変数の宣言を一元管理する方法は存じてなかったので、試してみました。
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/1093.txt
ただ上記は意図に沿った記述かどうか自信がありません。
それと、この件は今回のソースとは直接関係ないという認識で宜しいでしょうか?
仮に提示どおりソースを分割しても
class_list[] は sub.c でしか必要ないのかなと思ったので。

その後修正したもの
・ ソースを main.c, sub.c, var.h に分割しました。
・ 「フラグを構成する各要素」を resolver-1.pl のような感じに変更しました。

main.c(linux版)
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/1094.c
Makefile(linux版)
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/1095.txt
sub.c(linux版)
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/1096.txt
var.c(linux版)
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/1097.txt

No. 4398 # 68user 2005/11/16 (水) 03:05:19
>>4397 DNS勉強中
> http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/1093.txt
> ただ上記は意図に沿った記述かどうか自信がありません。
そういえばわたしには、複数ファイルから参照されるグローバル変数で、
宣言と初期化を同時に行った経験がありませんでした (わたしはこういう
場合は init_hoge() という関数を作るので)。

要は main.c で
    codelist_t class_list[];
    codelist_t class_list[] = {
        {"INTERNET", 1},
        ...
    };
となるわけですが、これはコンパイル通りますか? 少なくとも警告くらいは
出そうな気がします。

普通はどう書くんでしょうね>どなたか

> それと、この件は今回のソースとは直接関係ないという認識で宜しいでしょうか?
その通りです。

その他ソースについて。
> int soa_record_print(struct DNS_Response *DNS_response, char *print, int i)
引数が i というのはかなりいただけないので、record_num あたりで。

> for (i=0; type[i]!='\0'; i++)
> /* 照会タイプの文字の中に英小文字があれば英大文字に変換 */
> type[i] = toupper(type[i]);
そういえば strcasecmp(3) というライブラリ関数があるのを思い出しました
(使ったことはないですが)。

> void qr_print(int qr){
> codelist_t qr_list[] = {
> ...
> };
動作的には問題ありませんが、関数呼び出しのたびにスタックに qr_list の値が
積まれるのは無駄なので、一般的には
      static codelist_t qr_list[] = { ... };
とします。これだとスタックではなくヒープに置かれ、初期化は一度しか行われません。

> Makefile(linux版)
> http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/1095.txt
わたしなら以下のように書きますが、あまり Makefile に詳しくないので怪しげです。

    TARGET= domain_to_ip
    OBJS = main.o sub.o
    CFLAGS = -Wall
    $(TARGET): $(OBJS)
            $(CC) $(CFLAGS) -o $(TARGET) $(OBJS)
    .c.o: sub.h
            $(CC) $(CFLAGS) -c $<
    clean:
            rm -f *.o *~ core $(TARGET) $(OBJS)

あと、main がとても長くて汚い関数に見えますので、
    make_query();
    send_receive();
    parse_response();
の 3行か+エラー処理か、あるいは
    make_query();
    send_query();
    receive_response();
    parse_response();
の 4行+エラー処理くらいになるとよいかも、と思いました。

続く。

Prev< No. 4393〜4398> Next  [最新発言に戻る] [過去ログ一覧]