fchiba memo

2009年06月

http://www.ietf.org/rfc/rfc2396.txt
によると、
<scheme>://<authority><path>?<query>

path = [ abs_path | opaque_part ]
path_segments = segment *( "/" segment )
segment = *pchar *( ";" param )
param = *pchar
pchar = unreserved | escaped | ":" | "@" | "&" | "=" | "+" | "$" | ","

ということらしい。

つまり、; の後が parameter、? の後がqueryとなる。
しかも、parameterはsegment毎に複数かける。ということは、

http://example.com/dir1;a=1/dir2;b=2;c=3/index.html;d=4?f=5

なんてのもありってことだな。
ちゃんと解釈してくれるサーバーやフレームワークなんてなさそうだけど…。

実際問題、parameterなんて使うのはJavaのjsessionidぐらいしか見たことないんだが、
こいつのせいでいつも手間が増えるんだよなぁ。

puppetのtemplateで奇妙な挙動を発見。
テンプレート中で
<% name ||= 'default_name' %>

などと、変数のデフォルト値を設定しようとすると、manifestでどう書いてもdefault_nameが代入されてしまう。
しかも、
<%=name%>
<% name ||= 'default_name' -%>
<%=name%>
class xxx{
$name = 'true_name'
file{
content => template('test.erb')
}
}

とすると、
true_name
default_name

なんて生成される。(erbを直接rubyから実行するとtrue_nameが2回生成される)
puppet wikiを参考に
<% name = 'aaa' unless has_variable?('name') 

とすると、なぜかnameがnilになってしまう。

なぜ???
とりあえず、
<%
if has_variable?('name')
name2 = name
else
name2 = 'default_name'
end
%>
とし、name2を使えば問題が回避できた。

xen上に、ipvs(w/keepalived)でロードバランサを作ったが、再送が多発し速度がでない。

どうやら原因は、TCP offloadとxenの問題らしい(http://lists.graemef.net/pipermail/lvs-users/2007-August/019639.html)。

/sbin/ifup-local


DEVICE="$1"
case "$DEVICE" in
eth0)
ethtool -K $DEVICE tx off
;;
esac

と書いて解決。

アライドテレシスのルーター(AR415S)を使っていて起きたトラブル。

携帯向けのサイトを作っていたのだが、ドコモ携帯からのレスポンスが悪いという現象が発生した。最初は、ドコモだけ電波が悪いのかとも思ったのだが、コンテンツが大きくても小さくても常に1秒遅れるという奇妙な振る舞いだった。

原因を調べていくと、ルーターのTCP代理応答という機能に問題があることが判明。

この機能は、外から中へのTCP SYNパケットに対して、内側の機器が反応する前に、代理で返答してくれるというもの。(SYN Floodに対応するための機能らしい)

具体的には、

クライアント ルーター サーバー
| (1)SYN→ | |
| | (2)SYN→ |
| | (3)←SYN/ACK|
| (4)←SYN/ACK| |
| (5)ACK→ .| |
| | (6)ACK→ .|
| (7)データ→. .| |
| | (8)データ→. .|
| | (9)←ACK .|
| (10)←ACK | |
| … .| |



クライアント ルーター サーバー
| (1)SYN→ | |
| (2)←SYN/ACK| (A)SYN→ .|
| | (B)←SYN/ACK.|
| | (C)ACK→  |
| (3)ACK→ .| |
| (4)データ→. .| |
| | (5)データ→. .|
| | (6)←ACK .|
| (7)←ACK .| |
| … .| |

となる。(クライアント~ルーターのハンドシェイク((2)~(3))とルーター~サーバーのハンドシェイク((A)~(C))が独立して行われる。

今回、ドコモで問題となったのは、docomoのゲートウェイ(GW)が、(3)のACKのパケットにデータを乗せてきていたため、

ドコモ GW      ルーター    サーバー
 | (1)SYN→     |         |
 | (2)←SYN/ACK | (A)SYN→   .|
 |           | (B)←SYN/ACK |
 |          | (C)ACK→   |
 | (3)ACK+データ→ |        |このデータは捨てられてしまう
 |          |        |
 |          |        |GWは(3)に対するACKを待つが、サーバーには届いてないので来ない
 |          |        |
 | (4)データ再送→ |        |ACKが来ないので再送
 |          | (5)データ→ |
 |          | (6)←ACK  |
 | (7)←ACK     |        |
 |    …      |        |


となっていた。
その後の通信はスムーズに進むため、再送がかかるまでの時間((3)~(4))だけ遅れが発生していた。この時間がちょうど1秒。

体感的にも我慢のできない遅れであり、サーバーでもSYN Floodには対応できるため、この機能はオフにすることに。
DISABLE FIREWALL POLICY=policy TCPSETUPPROXY
というコマンドを入力し無事解決。

ところで、ハンドシェイクのACKにデータを乗せるってのはRFC的にアリなんだろうか???
(教科書的には、ACKとデータは別になってるよなぁ)
特に問題にはなっていないので、アリなんだとは思うが、あとで調べてみよう。

システム監視(nagiosなど)で異常検知した場合に、自動的に電話したい。

日中は携帯メールでもいいんだけど、寝ている最中に確実にたたき起こすにはやっぱ電話でしょ。
お金のあるところなら、24時間オペレーターが張り付いて電話するんだろうけど、うちには金が無い。

さてどうしたものか?

1.携帯メールで我慢する。その代わり着信音を長めに設定する。
 一番簡単に実現できるが、普段の着信音まで長くなる。
 いちいち、みんなに設定させるのも手間。

2.専用のサービスを使う。
 電話とコンピュータの組み合わせのソリューションはたくあんあり、CTIというらしい。
 が、コールセンターなどが主で、こんな小規模な用途向けのサービスはなさそう。

3.モデムをおいて発信。
 データセンターに電話線引くのが面倒。お金かかる。

4.Skype API on Linux で電話に発信(SkypeOut)
APIでどこまで操作できるか調査が必要。APIからも SkypeOut とかできるのか???

とりあえず最初は1.で。
その間に4.を調査してみよう。

とりあえず↓を買う予定
Skype API Book Vol.1Skype API Book Vol.1
(2006/08/23)
岩田 真一/rゆ/xai/池嶋 俊/大谷 弘喜/須崎 雅道/寺田 亮/谷萩 毅之/山本 達也

商品詳細を見る

このページのトップヘ