アーカイブ

Archive for 2009年9月

フレッツ・スクエア ネクスト対応ルータとBIND 9を協調させる

最近のフレッツ光対応ルータには、フレッツ・スクエア ネクストに対応した物があります。
フレッツ・スクエアは専用のPPPセッションを張る必要あり、フレッツ・スクエアv6はクライアントPCに専用ツールを入れる必要があったのですが、フレッツ・スクエア ネクストは特に何もしなくても接続できるという、大変気持ち悪い^h^h^h^h^h便利な代物です。

試しにウチからアクセスしてみたところ、初回のアクセスにかなり時間が経過した後に繋がり、その後なぜかLAN内のサーバに繋がらなくなるという面白展開になりました。
この時は、LANのプライマリDNSサーバへのflets-east.jpの問い合わせがタイムアウトして、セカンダリDNSになっていたフレッツ光対応ルータが応答して繋がり、その後ローカルマシンはプライマリDNSが死んだと誤解して、LAN内のホスト名を引けなくなっている、という顛末でした。

少し実験してみた所、フレッツ・スクエア ネクストは下記のような流れで接続している事が判りました。

  1. フレッツ光対応ルータに、flets-east.jpを問い合わせる
  2. IPv6のアドレスが返る
  3. クライアントがIPv6で接続しようとする
  4. フレッツ光対応ルータがIPv6ブリッジになってフレッツ・スクエア ネクストに接続する

つまりLANにDNSサーバがある場合、flets-east.jpの問い合わせがあった時に、フレッツ光対応ルータへフォワードすれば良いのです。
あと、僕らのような人種にありがちなミスは、ローカルマシンやブラウザでIPv6を無効に設定してしまう事です(^_^;;

ウチはDebian lennyでBIND 9を動かしていますが、以下のような設定を入れたらフレッツ・スクエア ネクストに問題なく繋がるようになりました。

vi /etc/bind/named.conf.local
+zone "flets-east.jp" {
+   type forward;
+   forward only;
+   forwarders {
+      <フレッツ光対応ルータのIPアドレス>
+   };
+};
広告
カテゴリー:サーバ

続・Darwin Calendar Serverの構築

2009年9月27日 6件のコメント

前回のエントリで紹介したDebian lennyにおいてのDarwin Calendar Serverの構築ですが、iCalのアカウントの委任タブの編集ボタンから他のユーザにカレンダーを公開しようとしても、ユーザ名が見つからないという残念な制限がありました。
が、この設定を行えるクライアント向けツールに気がつきました。今頃(^_^;;
CalDAVClientLibraryです。

インストール

ツールはスクリプトでSubversionリポジトリで公開されています。
ターミナルを開いて、下記のコマンドで取得します。

svn checkout http://svn.macosforge.org/repository/calendarserver/CalDAVClientLibrary/trunk CalDAVClientLibrary

委任設定

cd CalDAVClientLibrary
./runshell.py --server=http://<サーバのホスト名>:8008 --user=<公開する側のユーザID>
Password:<公開する側のユーザのパスワード>
/ > proxies -i
Proxy > add -r
New principal [q - quit]: /principals/users/<公開する相手のユーザID>
Proxy > quit
/ > quit

シェルモードにはヘルプもあるので、先に読むと良いです。

CalDAVClientLibraryにはrunadmin.pyというコマンドもあって、こちらはサーバー上でaccounts.xmlの編集に使えます。
ドキュメント不足で手書き設定が判りにくいので、このツールで編集した方が良いと思います。
コマンドの使い方はヘルプですぐ判りますし、値の指定は対話形式なので問題ないと思います。

カテゴリー:サーバ

Darwin Calendar Serverの構築

連休前に会社のリポジトリサーバをDebian lennyで組むというミッションがあったのですが、Debianの出来の良さが気に入ったので自宅のサーバも換装してみました。
怪しげなリポジトリの追加やコンパイル作業無しで必要なサービスが揃ったのは初めてで、Debianのパッケージの充実に感動している所です。

せっかくなので、今まで先送りしていて欲しかったCalDAVサーバを構築してみる事にしました。
lennyのリポジトリを確認した所、Darwin Calendar Serverが見つかりました。
DAViCalの方は、squeeze以降にしか無いようです。

先に使用感について書いておきますが、概ね良好です。
MacのiCalとiPhoneから、問題なく読み書きできています。
自宅サーバを持っている人で、MobileMeやGoogle Calendarにスケジュールを預けたくないけど、OTA同期したい人にはお勧めできます。
一点だけ問題があり、iCalからカレンダーを他のユーザに委任する事ができません。
Calendar Serverのメーリングリストを追ったところ、アカウントをLDAPで管理するように構成しなければ、この機能が動作しないという事でした。
自宅サーバに家族のアカウントを収容していて、相互にカレンダーの公開を考えている場合は面倒かもしれません。
僕は、LDAPは構成しませんでした。面倒すぎ(^_^;;

インストール

aptitude install calendarserver

ディスクの拡張属性を有効化

Calendar Serverは、情報の一部のファイルの拡張属性に収容します。
/var/spool/caldavを含むディスクを、user_xattr付でマウントするようにしてください(ext3の場合)。
下記は僕の所の例ですが、ファイルシステムでオプションが違うと思うので、調べてください。

vi /etc/fstab
-/dev/md0        /               ext3    errors=remount-ro 0       1
+/dev/md0        /               ext3    errors=remount-ro,user_xattr 0       1

ルートディスクの場合はアンマウントできないので、再起動かもしれません。

設定ファイルを用意

インストール直後は設定ファイル不足で起動しないようになっています。
サンプルをコピーしてから始めると楽です。

cp /usr/share/doc/calendarserver/examples/accounts.xml /etc/caldavd
cp /usr/share/doc/calendarserver/examples/sudoers.plist /etc/caldavd

ネットワーク設定

デフォルトだとlocalhostにバインドされているので、すべてのIPアドレスに応答するように設定します。
またSSLを有効にする場合は、証明書も指定します。

vi /etc/caldavd/caldavd.plist
-  <!--
   <key>SSLPort</key>
   <integer>8443</integer>
-  -->

   <key>BindAddresses</key>
-  <array><string>localhost</string></array>
+  <array><string></string></array>

   <key>SSLCertificate</key>
-  <string>/etc/ssl/certs/ssl-cert-snakeoil.pem</string>
+  <string>/etc/ssl/certs/<証明書></string>

   <key>SSLPrivateKey</key>
-  <string>/etc/ssl/private/ssl-cert-snakeoil.key</string>
+  <string>/etc/ssl/private/<秘密鍵></string>

ユーザを追加

ユーザ情報はXMLファイルに書き込みます。
パスワードも生ですし、PAMを使ってLinuxのアカウントで認証する事もできません。
LDAPを使って構成すると幸せになれるみたいですが……

vi /etc/caldavd/accounts.xml
+  <user>
+    <uid>user1</uid>
+    <password>pass1</password>
+    <name>User 1</name>
+    <cuaddr>user1@foo.com</cuaddr>
+  </user>
+  <user>
+    <uid>user2</uid>
+    <password>pass2</password>
+    <name>User 2</name>
+    <cuaddr>user2@bar.com</cuaddr>
+  </user>

試していませんが、会議室予約のような共有カレンダーはLDAP無しでも設定可能であるようです。
accounts.xmlの下の方にそれっぽいサンプルがあるので、お試しください。

自動起動を設定

デフォルトで起動が禁止されています。

vi /etc/default/calendarserver
-#start_calendarserver=yes
+start_calendarserver=yes

後は起動するだけです。

/etc/init.d/apache2 calendarserver

クライアントからの接続

iCalやiPhoneからの接続は簡単です。
ホスト名とユーザ名とパスワードを入れれば、SSLの有無やカレンダーのパスを自動的に検出してくれます。
Windowsからの接続は試していませんが、Mozilla Sunbirdなら繋がると思います。たぶん(^_^;;

カテゴリー:サーバ

C#で動的なハイポートで待ち受けるWebサーバを実装する

ニーズが解りにくいかもしれませんが、LAN内で通信するアプリケーションを実装する時に、通信プロトコルとしてHTTPを選択するケースが該当します。
ランダムなハイポートにどうやって接続するんだと疑問に思うかもしれませんが、ポート番号はZeroconfなどでブロードキャストします。
利点としてはIANAにポート番号を登録したり、衝突覚悟で使う必要が無いという事をあげておきます。

C#でWebサーバを実装する場合、真っ先に思いつくのはSystem.Net.HttpListenerクラスだと思いますが、このクラスは以下の理由で今回の目的には使えません。

  • ポート番号に0を指定して、カーネルに動的なハイポートを割り当てさせる事ができない。未確認なので0を受け付ける可能性もあるが、少なくても割り当て後のポート番号を確認する方法が無い。
  • ファイアーウォールに除外設定を行う方法が無い。HttpListenerは通信をhttp.sysの中で行うため、プロセス名を指定して除外設定を行う事ができない。また、利用するポート番号はランダムなので、ポート番号を指定して除外する事もできない。

そこで、アプリケーションに埋め込み可能なHTTPサーバの実装を探してみたんですが、C# WebServerという物がありました。
すべてC#で書かれていて、Apacheライセンスです。
試したところ、ポート番号0を指定すると例外を投げます。また、リスン開始後のポート番号を確認する方法もありません。
そこで、パッチを作成しました。
ポート番号に0を指定するとランダムなハイポートを割り当てます。
また、割り当てたポート番号を読み出せるプロパティを追加しました。

パッチはプロジェクトにポストしました。
マージしてくれると、メンテが楽なんですが……。

カテゴリー:開発 タグ:

iPhone OS 3.0のUIActionSheetは動的メニューとして使える

dynamic_action_sheet
なぜなら、項目を何件でも表示できるから。

iPhone OS 2.xまでのUIActionSheetは、項目の件数が増えると画面上にはみ出してしまって、ボタンが押せなくなってしまう限界があり、件数に限界がありました。
iPhone OS 3.0のUIActionSheetはこの部分が改良されて、はみ出る時は自動的にリスト表示に切り替わります。

カテゴリー:開発 タグ: ,

C99とC++の変数宣言の非互換

2009年9月7日 2件のコメント

iPhone開発をやるようになってから、ずっと気になっていた事があります。下記のコードが、コンパイラを通らないのです。

int main() {
    int n;
    switch (n) {
        case 0:
            int x = 1;
        break;
    }
}

int x = 1;の所で、「error: expected expression before ‘int’」となります。

気がついた当時は、gccのObjective-Cコンパイラに、変数スコープルールのバグがあるのではないかと考えて、次のような回避コードを書いていました。

int main() {
    int n;
    switch (n) {
        case 0:
            {
                int x = 1;
            }
        break;
    }
}

所がある日、次のようなコードがコンパイラを通る事に気がつきました。一瞬、目の錯覚かと。

int main() {
    int n;
    switch (n) {
        case 0:
            ;
            int x = 1;
        break;
    }
}

念のため、最初のコードをC++コンパイラに通してビルドできる事を確認、さらにCコンパイラを試したら、エラーになりました。つまりObjective-Cではなく、C言語レベルで引っかかっていたのです(例はintですが、見つけた時はNSStringか何かでした)。

ここまできてやっと、caseラベルが変数宣言文をエラーにしていると気がつきました。次のコードは、Cコンパイラでエラーになります。

int main() {
test:
    int x = 1;
}

納得いかない仕様ですが、C99とC++の変数宣言には非互換があるという事になります。JISを当たってみましたが、それらしき制約を見つけられないです…

カテゴリー:開発 タグ:

Cocoa勉強会で発表してきました

MailMeの変なキャラのアニメーションの実装について発表してきました。

発表後のQAで、Core Animationを誤用していた事が発覚。フレームアニメをやりたい時は、contentsプロパティを書き換えれば良かったんですよ。@narumij、ありがとうございます。

カテゴリー:開発