ぽんこつプログラマーの日々のまとめ
sox


SOCKSプロトコルを利用した日本語ドキュメントやサンプルがあまりないのでメモ書き。
※SOCKS 5、TCP/IP通信とする。

参考:
RFC 1928
wikipedia
SOCKS(SOCKetS)通信リンク集~靴下じゃないよ~ネットワークプログラミング




1.まず通信するためのSocketクラスを用意し、SOCKSサーバーに接続する
Imports System.Net
Imports System.Net.Sockets

Dim socks As Socket = New Socket((AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
Dim proxyIP As String = "localhost" ' ドメイン名 IPでも可
Dim proxyPort As Integer = 8080
socks.Connect(proxyIP , proxyPort )

2.最初の挨拶を送る
Dim bMes As Byte() = New Byte() {&H5, &H1, &H0}
Dim iMes = res.Send(bMes, bMes.Length, SocketFlags.None)
Byte型配列を送るのだが、中身にお約束がある。
■要素1[bMes(0)]
SOCKSのバージョン。今回は5を対象とするが、4で繋げる場合は&H4に変更しよう。
■要素2[bMes(1)]
サポートされた認証方法の数,1バイト
■要素3[bMes(2)]
認証方法, 可変長, サポートされたメソッドにつき1バイト
00認証なし
01GSSAPI
02ユーザ名/パスワード
03-7FIANA により割り当てられたメソッド
80-FEプライベート使用のために予約されたメソッド
この例では認証なしでの接続となる。

3.サーバーの応答を受け取る
bMes = New Byte(1) {} 
iMes = res.Receive(bMes, bMes.Length, SocketFlags.None)
bMesに値が詰まり返ってくる。
■要素1[bMes(0)]
SOCKSのバージョン。この例では5が帰ってくる。
■要素2[bMes(1)]
選択した認証方法。サーバーが指定した認証方法に対応していない場合はFFが返る。

4.必要に応じてユーザー情報を送信する
今回の例では上記で”認証なし”を送っているので必要ないが、ユーザー認証が必要な場合は下記のように送信する。
Dim enc As System.Text.Encoding = System.Text.Encoding.UTF8
Dim bName As Byte() = enc.GetBytes("hoge") 'ユーザー名
Dim bPass As Byte() = enc.GetBytes("fuga") 'パスワード

Dim sAut As List(Of Byte) = New List(Of Byte)
sAut.Add(&H5)
sAut.Add(CByte(bName.Length))
sAut.AddRange(bName)
sAut.Add(CByte(bPass.Length))
sAut.AddRange(bPass)

bMes  = sAut.ToArray()
iMes = res.Send(bMes, bMes.Length, SocketFlags.None)
■要素1
SOCKSのバージョン 1バイト
■要素2
ユーザー名の文字長 1バイト
■要素3
ユーザー名
■要素4
パスワードの文字長 1バイト
■要素5
パスワード

送信後、受信すると以下が返る。
■要素1
SOCKSのバージョン 1バイト
■要素2
認証結果 0で成功 それ以外は失敗 1バイト

5.接続要求を送信する
' アドレスの設定
Dim hostIP As String() = Dns.GetHostEntry("www.xxx.yyy").AddressList(0).ToString.Split(".")
Dim hostPort As String = Convert.ToString(8080, 16)
If hostPort .Length < 3 Then hostPort = "00" & hostPort
Dim p1 As Byte = Convert.ToByte(str.Substring(0, 2), 16)
Dim p2 As Byte = Convert.ToByte(str.Substring(2, 2), 16)
' Ipv4接続 sMes = New Byte() {&H5, &H1, &H0, &H1, _ CInt(hostIP(0)), CInt(hostIP(1)), _ CInt(hostIP(2)), CInt(hostIP(3)), _ p1, p2} rMes = res.Send(sMes, sMes.Length, SocketFlags.None)
■要素1
SOCKSのバージョン 1バイト
■要素2
コマンドコード 1バイト
01TCP/IP ストリーム接続を確立する
02TCP/IP ポートバインディングを確立する
03UDP ポートを結合させる
■要素3
RESERVED 00固定
■要素4
アドレスタイプ 1バイト
01IPv4 アドレス
03ドメイン名
04IPv6 アドレス


Add Comments

名前
 
  絵文字
 
 
webmaster

Redmusk

最西端の地で釣りとギターとゲームをこよなく愛する本業ぽんこつプログラマー。今を生きるを座右の銘とし日々快楽だけを求め切磋琢磨しております。

soundcloud