maaash.jp

what I create

UDPホールパンチング整理(わかったかも)

わかったのかも → コメント参照

symmetric NAT以外の話、つまりFull Cone NAT,Restricted Cone NAT,Port-Restricted Cone NATなら
UDPホールパンチングを使って外から中向けのセッションを張れるようだ。

Full Cone NATとは
NAT内からNAT外へ出る(UDP)パケットを送って、マッピングをつくったら、
NAT外のどのIP,ポートからでも、そのマッピングを利用してNAT内にパケットを送ることのできるNAT。

Restricted Cone NATとは
Full Cone NATに加えて、一度NAT内からパケットが送信されたIPからのみ、そのマッピングを利用できるNAT。

Port-Restricted Cone NATとは
Restricted Cone NATに加えて、一度NAT内からパケットが送信されたIPとポートからのみ、そのマッピングを利用できるNAT。

Symmetric NATとは
NAT内からNAT外へ出るパケットを送って、マッピングを作っても、
その同じ宛先からのみ、マッピングを利用できるNAT。
逆に言うと、
NAT内からNAT外へ出るパケットを送って、マッピングを作っても、
違うIPとポートの組み合わせからはそのマッピング(=NATの外側のIPとポート)からはNAT内にパケットを送れないNAT。
こいつに対してはTURNを使う。

簡略化のためIPは省略、Full Cone NATもRestricted Cone NATもPort-Restricted Cone NATも同じだから
一番厳しいPort-Restricted Cone NATだと思って考える

A< ——–>NAT1(port6000)< ——–>STUNサーバ< ——–>(port10000)NAT2< ——–>B

  1. まず、AとSTUNサーバ、BとSTUNサーバは別々につながってる。
    AはNAT1の外側ポート6000番を通してSTUNサーバと、
    BはNAT2の外側ポート10000番を通してSTUNサーバとつながってる

A< ——–>NAT1(port6000)< ——–>STUNサーバ< ——–>(port10000)NAT2< ——–>B

  1. STUNサーバが外側ポートを教える
    STUNサーバは、Aに対して、「BはNAT2のport10000番にいるよ」って言う
    STUNサーバは、Bに対して、「AはNAT1のport6000番にいるよ」って言う

A< ——–>NAT1(port6000)< ——–>STUNサーバ< ——–>(port10000)NAT2< ——–>B
A———>NAT1(port6002)————–>—————>x(port10000)NAT2                      B

  1. AはNAT2のport10000に送ってみる
    だがNAT2内からNAT1宛てにパケットが送られていないのでマッピングが無い。
    NAT2ではじかれる
    ここで、AからNAT2へ向けていったパケットは、NAT1の6002とか、6000ではない番号から出て行くだろう?
    NATの外側ポートって変わらないのかな?

A< ——–>NAT1(port6000)< ——–>STUNサーバ< ——–>(port10000)NAT2< ——–>B
A                 NAT1(port6000)x< —————————–(port10002)NAT2<———B

  1. BからNAT1のport6000に送ってみる
    NAT1には、AからNAT2のport10000番へ向けて送ったマッピングがあるが、
    NAT2の外側ポートは10002とか、10000ではない番号から出て行く(?)。
    NAT2のport10002番から来ているので、ポート番号が違うのでマッピングは利用できない
    NAT1ではじかれる

3,4ではじかれるように、STUNサーバではないやつに対してパケット送った時に
NATの外側ポートが変わっちゃうと困るよね?
それが、昨日ちょろっと話していた、keep_alivedみたいなことでNATの外側ポートを変えずにいけるのかな?

とりあえず、Full Cone NATと、IP Restricted Cone NATの組み合わせまでならいけるんだろうなということはわかった。

Port Restricted Cone NATでもいけるの?
誰か教えて!

第十二回SIProp勉強会行ってきた

全員初めてなのになんとかなりましたね。
みなさま(お酒が入ったせいか)話やすい人たちでよかったです。
ありがとうございました!

今日せんえつながら発言したadobeのP2Pのことは
FlashPlayer10のP2Pに過去書きましたよ。
正直P2P界では今Adobeに一番注目してます。

セキュリティの話とかちんぷんかんぷんでしたが、
P2PSIPはあれだなぁ、ってみんな思ってるってことはわかりましたw
標準は泥臭いところから生まれる方が現実的なモノができやすいのでしょう。

ということで、セッション層はXMPP使うことにする。
まだ悩むのはlibjingleをがんばって使うか、C#で自分で実装しにいくか、、

トランスポート層はUDPかなぁ
TCPのNAT越えは
Characterization and Measurement of TCP Traversal through NATs and Firewalls
がちゃんとしたまとめっぽいけど、実現方法がきもいよなぁ、
今日もTCPがNAT超えられるの5割程度って言ってたしUDPでなんとかしよう

UDPのSTUNの仕組みがまだ理解できてないなぁ

フルコーンNAT → STUNサーバ にパケット送ってNATにマップを作らせることで
外部IP → フルコーンNAT内 方向が到達できる、ってのはわかったし実験できたんですが、

SymmetricじゃないNAT(IP制限のみかポート制限のみ)内から、SymmetricじゃないNAT内にメッセージを送る手順がわからない。
まずSTUN=UDPホールパンチングだと思ってたけど、今日の話の流れを考えると違うっぽいな
もうちょい調べよう

その上はRTPでSPEEXを包めばいいかなぁ、
FlashPlayer10でSPEEX対応した時に、ローカルアプリからブラウザのFP10にSPEEXストリーム流せたらすごい

nellymoser encoderに期待

ffmpegのnellymoserデコーダー試そうと思っていろいろみてたら
Google Summer of Code 2008で
Title Nellymoser Encoder

abstract: The Nellymoser Asao codec is a proprietary single-channel (mono) format optimized for low-bitrate transmission of audio, developed by Nellymoser Inc. The codec optimized for real-time and low-latency encoding of audio. Adobe Flash Player clients, when recording audio from a user’s microphone, use the Nellymoser Asao codec and do not allow Flash programmers to select any other codec. My main goal will be writing Nellymoser encoder.

というのを発見。
期待

ffmpegでnellymoserデコード

こんな感じ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
santrini% ffmpeg -i 2008\_08\_29\_11\_17\_49.flv -ar 44100 2008\_08\_29\_11\_17\_49.mpg  
FFmpeg version git-c0390c6, Copyright (c) 2000-2008 Fabrice Bellard, et al.  
configuration:  
libavutil 49.10. 0 / 49.10. 0  
libavcodec 51.69. 0 / 51.69. 0  
libavformat 52.21. 0 / 52.21. 0  
libavdevice 52. 1. 0 / 52. 1. 0  
built on Aug 29 2008 11:49:02, gcc: 4.3.1  
Input #0, flv, from '2008\_08\_29\_11\_17_49.flv':  
Duration: 00:00:23.21, start: 0.000000, bitrate: N/A  
Stream #0.0: Video: flv, yuv420p, 320x240, 1000.00 tb(r)  
Stream #0.1: Audio: nellymoser, 8000 Hz, mono, s16  
Output #0, mpeg, to '2008\_08\_29\_11\_17_49.mpg':  
Stream #0.0: Video: mpeg1video, yuv420p, 320x240, q=2-31, 200 kb/s, 60.00 tb(c)  
Stream #0.1: Audio: mp2, 44100 Hz, mono, s16, 64 kb/s  
Stream mapping:  
Stream #0.0 -> #0.0  
Stream #0.1 -> #0.1  
Press [q] to stop encoding  
frame= 1381 fps= 0 q=5.5 Lsize= 1108kB time=23.00 bitrate= 394.6kbits/s  
video:913kB audio:181kB global headers:0kB muxing overhead 1.223595%  

red5で録画&録音したflvをmpgに。
-ar 44100 はオーディオのサンプリングレート。nellymoserの8000Hzじゃmp2にエンコードできないよって怒られるから。
ffmpegは FFmpeg Download and SVN
から

1
2
3
4
5
git clone git://git.mplayerhq.hu/ffmpeg/  
cd ffmpeg  
./configure  
make  
sudo make install  

できたmpgはそのままyoutubeへアップ可能
簡単

Debian Linux に Skype をインストールする備忘録

http://www.skype.com/intl/ja/download/skype/linux/choose/

このページの Debian Etch クリックしてダウンロードできるdebパッケージは
こうなる

euboea% sudo dpkg -i skype-debian_2.0.0.72-1_i386.deb
dpkg: skype-debian_2.0.0.72-1_i386.deb.ng の処理中にエラーが発生しました (–install):
パッケージアーキテクチャ (i386) がシステム (amd64) と一致しません
以下のパッケージの処理中にエラーが発生しました:
skype-debian_2.0.0.72-1_i386.deb

Dynamicをダウンロードして解凍、skypeを実行すると
こうなる

euboea% ./skype
./skype: error while loading shared libraries: libasound.so.2: cannot open shared object file: No such file or directory

euboea% locate libasound.so.2
/usr/lib/libasound.so.2
/usr/lib/libasound.so.2.0.0
euboea% ldd skype
linux-gate.so.1 => (0xffffe000)
libasound.so.2 => not found
libXv.so.1 => not found
libXss.so.1 => not found
librt.so.1 => /lib32/librt.so.1 (0xf7f67000)
libQtDBus.so.4 => not found
libQtGui.so.4 => not found
libQtNetwork.so.4 => not found
libQtCore.so.4 => not found
libpthread.so.0 => /lib32/libpthread.so.0 (0xf7f4f000)
libstdc++.so.6 => not found
libm.so.6 => /lib32/libm.so.6 (0xf7f2a000)
libgcc_s.so.1 => /usr/lib32/libgcc_s.so.1 (0xf7f1d000)
libc.so.6 => /lib32/libc.so.6 (0xf7dd6000)
/lib/ld-linux.so.2 (0xf7f7a000)
libX11.so.6 => not found
libXext.so.6 => not found

あちゃあ

euboea% file skype
skype: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.4.1, stripped

32bit。。

euboea% sudo apt-get install ia32-libs ia32-libs-gtk

これでOK
RedHatではどうあがいても動かなかったのにさすがDebian

[perl]TheSchwartzのWorkerにIDをつける

こういうときはどうやってやるのがいいのかなぁ
・なんか限れられた数のリソース(例えば、DISPLAYとか?、)があって、リソースにはTheSchwartzのWorkerを1対1対応させて、Workerを動かしたい
・Jobをinsertする方はどのWorkerに仕事させるか意識したくない

Jobをinsertする方はこんな
feeder.pl

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env perl  
use strict;
use warnings;
use FindBin;
use File::Spec;
use YAML::Syck;
use TheSchwartz;

my $conf = LoadFile( File::Spec->catfile($FindBin::Bin, &#8216;..&#8217;, &#8216;myapp.yml&#8217;) );  
my $pool = TheSchwartz->new( %{ $conf->{TheSchwartz}{args} } );
$pool->insert(&#8216;MyApp::SleepWorker&#8217;);  
1;

0~9秒間の間でランダムな秒数寝るだけのWorkerを起動させるpl。
こいつを複数プロセス動かして、それぞれは自分に割り当てられてるリソースを知っている、っていう状態をつくりたい。
workの引数になんか入れてもだめっぽいので、、

worker.pl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/env perl  
use strict;
use warnings;

use FindBin;
use File::Spec;
use lib File::Spec->catfile( $FindBin::Bin, &#8216;..&#8217;, &#8216;lib&#8217; );  
use YAML::Syck;
use TheSchwartz;
use MyApp::SleepWorker;

my $conf = LoadFile( File::Spec->catfile($FindBin::Bin, &#8216;..&#8217;, &#8216;myapp.yml&#8217;) );  
my $worker = TheSchwartz->new( %{ $conf->{TheSchwartz}{args} } );
$worker->can_do(&#8216;MyApp::SleepWorker&#8217;);  
$worker->work;

1;

環境変数なのかなぁ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package MyApp::SleepWorker;
use strict;
use warnings;
use base qw/TheSchwartz::Worker/;

sub work {
my ( $class, $job ) = @_;
my ($data) = $job->arg;

my $worker\_id = $ENV{WORKER\_ID};
print &#8220;[$worker_id]worker start\n&#8221;;

my $sleep_time = int(rand(10));
print &#8220;[$worker\_id]sleep: $sleep\_time\n&#8221;;  
sleep( $sleep_time );

print &#8220;[$worker_id]end\n&#8221;;  
$job->completed;
}

1;

boot_worker1, boot_worker2

1
2
3
4
5
6
7
#!/bin/sh  
export WORKER_ID=1
./worker.pl&#038;

#!/bin/sh  
export WORKER_ID=2
./worker.pl&#038;  

“` % ./boot_worker1; ./boot_worker2
% ./feeder.pl; ./feeder.pl;./feeder.pl; ./feeder.pl;./feeder.pl; ./feeder.pl;./feeder.pl; ./feeder.pl;
[2]worker start
[2]sleep: 8
[1]worker start
[1]sleep: 4
[1]end
[1]worker start
[1]sleep: 9
[2]end
[2]worker start
[2]sleep: 5
[2]end
[1]end
[2]worker start
[2]sleep: 9
[1]worker start
[1]sleep: 8
[1]end
[1]worker start
[1]sleep: 8
[2]end
[2]worker start
[2]sleep: 2
[2]end
[1]end[/code]

自分のIDを意識しながら動けてる

オープンソースなbittorrent-trackerまとめ

trackerとは、torrentファイルDLした後につなぎにいって、本体ファイルをDLするための接続先ピアの一覧を返すサーバ。
どれがいいんだろ

○公式bittorrentのbittorrent-trackerサーバ
 maybe slow..
 http://www.bittorrent.com/
 http://download.bittorrent.com/dl/
 pythonで動いてる
 ./bittorrent-tracker.py –port 6969 –dfile dstate

○apache2とmod_btの組み合わせ
 http://www.crackerjack.net/mod_bt/mod_bt.html
 裏でlibbttrackerを使用
 Net::BitTorrent::LibBT::Tracker これでそこにつなげるかも

○Net::BitTorrent::LibBT::Tracker 使って自前perlサーバ
 mod_bt の libbttrackerのperlから使う

○Open Tracker
 http://erdgeist.org/arts/software/opentracker/
 http://opentracker.blog.h3q.com/
 It aims for minimal resource usage and is intended to run at your wlan router.

○The Hydra Project
 A Distributed, private BitTorrent tracker framework with goals of:
 … user privacy, anonymity, survivability & distributed ratio maintainability.
 The primary goal of this project is to replace the aging TorrentBits code employed by most private torrent trackers today.
 http://code.google.com/p/hydraproject/
 ruby on rails

○PHPBTTracker+
 http://phpbttrkplus.sourceforge.net/
 mysql、apache1/2
 でもphp使うなら純正pythonの使うよ

×TorrentBits
 http://sourceforge.net/projects/torrentbits
 last modified at 2005

×libTorrent and rTorrent これはclient??
 http://libtorrent.rakshasa.no/wiki
 http://fedoratutorials.com/2007/05/27/rtorrent-an-introduction/

×Gazelle
 http://projectgazelle.org/
 まだclosed source
 C++ based tracker, a PHP frontend, and a complete admin-panel

×BNBT 最後のリリースが2004/10/20
 http://wiki.depthstrike.com/index.php/BNBT:Main_Page
 BNBT is a complete port of the original Python-based BitTorrent tracker to C++ for speed and efficiency
 http://sourceforge.net/project/showfiles.php?group_id=126751

×Bit Torrent Kit [Windows]
 http://bittorrentkit.sourceforge.net/

×BitComet Tracker [Windows]
 http://www.bitcomet.com/tools/tracker/index.htm

×osprey last updated in 2006

FlashPlayer10のP2P

Peer to Peer (P2P) in Flash Player 10 beta
ho-

利用シーンに関わる部分はここ。

Will RTMFP enable massive file-sharing applications through Flash Player 10 beta?
No. Large-scale file-sharing network applications rely on the ability to read from and write to the hard drive constantly to only load parts of files into memory when needed. In Flash Player 10 beta you can load files from the desktop to the Flash Player runtime, but the file would need to be loaded manually by the end-user and remain in memory for the entire time the file would be needed. The drain on system resources would make this style of application impractical.

ファイル共有的な使い方には向かない。
FlashPlayer10でローカルのファイルを扱えるようになったとはいえ、ローカルのファイルをロードするにはユーザーの操作が必要だし、ファイル交換的な使い方をするには、ファイルを全部メモリにのっけることになるから。

RTMFP(RealTimeMediaFlowProtocol)ってのができて、次期FMSがそれをサポートするそう。
今はその次期FMSが無いからFP10Betaにはのってるけど試せないねーって。

RTMFPの資料探したら少しあった。
Real‐Time Media Flow Protocol Frequently Asked Questions ‐ External
Real Time Media Flow Protocol
PureなP2Pではなくて、次期FMSによってコネクションIDを管理される、ようです。

red5すぐ対応するといいなぁ

Download the ActionScript 3.0 Language Reference, which provides information on the syntax and usage of the new APIs in Flash Player 10
新しいas3のリファレンス見るといろいろ追加されてんなぁ
NetStream.onPeerConnect
NetStream.peerStreams
NetStream.DIRECT_CONNECTIONS
楽しみ。

NetStream.play2
とかあるところがまだbeta感あるねw

[git]gitに入門してみた

svn使ってます
myappの下には、trunk, tags, branches がある状態

1
2
3
4
git svn init -s https://path/to/myapp/ myapp  
cd myapp  
git svn fetch[/code]  
これに時間かかる

git checkout trunk[/code]
これがちょっぱやでびびるなぁ

編集した後、

1
2
3
4
5
6
7
git add file1 file2 file3  
git commit -m"[edited file1,2,3]"[/code]  
ローカルへのコミットは気軽にしていいみたい

perlのcatalystアプリで、myapp_local.yml とかもろもろローカルで変更しているのがあるので、  
そいつらがある状態で  
svnにコミットしようとすると、  

Cannot dcommit with a dirty index. Commit your changes first, or stash them with `git stash’.[/code]
って怒られる

1
2
3
4
git stash[/code]  
ってやるとmyapp_local.ymlとかdirtyなファイル達がどっかに退避されるみたい

そこで  

git svn dcommit
[/code]
するとsvnにコミットできる

1
2
3
4
5
6
7
8
9
10
git stash apply  
[/code]  
ってやると退避したのが帰ってくる。

そして  
<a href="http://unknownplace.org/memo/2008/02/19#e002" onclick="javascript:_gaq.push(['_trackEvent','outbound-article','http://unknownplace.org/memo/2008/02/19#e002']);">18:09 zsh の prompt に git のブランチ情報を表示</a>  
これやるべし、と思ったけど、書いてあるようにハッシュ値が出ますよ!  
今のcoderepos版でも。

gitのとこ、↓こうしたら一時的にokだったけど、まだだめみたい。  

perl

git

if (-d “$path/.git” && -f “$path/.git/HEAD”) {
my $branch;

my $head = file(“$path/.git/HEAD”)->slurp;
chomp $head;

if ($head =~ /^\w{40}$/) { # no local branch?

my $refs = qx( grep $head -l $path/.git/refs/remotes/{,**/}* );

if ($refs =~ m!.git/refs/(\S+)!) {

# $branch = $1;

}

my $refs = qx( grep $head $path/.git/info/refs );
if ( $refs =~ m!refs/remotes/(\S+)!) {
$branch = $1;
}
}
elsif ($head =~ m!ref: refs/heads/(\S+)!) {
$head = $1;
}

print ‘(‘, ($branch || $head), ‘)’;
exit;
}
“`

なんとかしたいなー

[skype api]skypeで電話をかけ指定のwavを再生して切断

skypeで電話をかけ指定のwavを再生して切断。
フレームレート16kHz、16bitサンプリングのwavを再生できる。
44.1kHzのはNGでした。
skypeは
DISPLAY=127.0.0.1:0.0
で立ち上がっている。

再生できるんだけど、
再生開始後の数秒間、音程が異常に崩れる。。
なんかおまじないがあるのかなぁ

[python]

!/usr/bin/python

# -*- coding: utf-8 -*-

# コマンドラインで指定したskypeidに電話をかける

import Skype4Py
import sys
import os

os.environ[‘DISPLAY’] = ’127.0.0.1:0.0′

# This variable will get its actual value in OnCall handler
CallStatus = 0

# Here we define a set of call statuses that indicate a call has been either aborted or finished
CallIsFinished = set ([Skype4Py.clsFailed, Skype4Py.clsFinished, Skype4Py.clsMissed, Skype4Py.clsRefused, Skype4Py.clsBusy, Skype4Py.clsCancelled]);

def AttachmentStatusText(status):
return skype.Convert.AttachmentStatusToText(status)

def CallStatusText(status):
return skype.Convert.CallStatusToText(status)

# This handler is fired when status of Call object has changed
def OnCall(call, status):
global CallStatus
CallStatus = status
print ‘Call status: ‘ + CallStatusText(status)
if status == Skype4Py.clsInProgress:
print ‘ playing wav’
call.InputDevice( Skype4Py.callIoDeviceTypeFile ,’/home/mash/skype/01_16bit_16kHz.wav’ )

HasConnected = False
def OnInputStatusChanged(call, status):
global HasConnected
print ‘InputStatusChanged: ‘,call.InputDevice(),call,status
print ‘ inputdevice: ‘,call.InputDevice()

# 一度CallInputStatusがTrueになった後、Falseになったら、ファイルの再生が終了してる(はず)
if status == True:
HasConnected = True

if status == False and HasConnected == True:
print ‘ play finished’
call.Finish()

# This handler is fired when Skype attatchment status changes
def OnAttach(status):
print ‘API attachment status: ‘ + AttachmentStatusText(status)
if status == Skype4Py.apiAttachAvailable:
skype.Attach()

# Let’s see if we were started with a command line parameter..
try:
CmdLine = sys.argv[1]
except:
print ‘Missing command line parameter’
sys.exit()

# Creating Skype object and assigning event handlers..
skype = Skype4Py.Skype()
skype.OnAttachmentStatus = OnAttach
skype.OnCallStatus = OnCall
skype.OnCallInputStatusChanged = OnInputStatusChanged

# Starting Skype if it’s not running already..
if not skype.Client.IsRunning:
print ‘Starting Skype..’
skype.Client.Start()

# Attatching to Skype..
print ‘Connecting to Skype..’
skype.Attach()

# Checking if what we got from command line parameter is present in our contact list
Found = False
for F in skype.Friends:
if F.Handle == CmdLine:
Found = True
print ‘Calling ‘ + F.Handle + ‘..’
skype.PlaceCall(CmdLine)
break

if not Found:
print ‘Call target not found in contact list’
sys.exit()

# Loop until CallStatus gets one of “call terminated” values in OnCall handler
while not CallStatus in CallIsFinished:
pass

[/python]