Giter Club home page Giter Club logo

yanfd's Introduction

YaNFD - Yet another Named Data Networking Forwarding Daemon

YaNFD is a forwarding daemon for the Named Data Networking platform written in Go. It is compatible with existing NDN applications and utilizes the management tools and protocols developed for the NFD forwarder.

Prerequisites

YaNFD requires Go 1.20+, although it may be possible to use older versions of Go. Besides that, you will need libpcap and g++ on Linux and MacOS. On Ubuntu, these libraries can be installed by:

sudo apt install build-essential pkg-config libpcap-dev

You may refer to this if you want to build a Docker image.

YaNFD has been developed and tested on Linux (namely, Ubuntu). However, we have designed it with support for Windows, macOS, and BSD in mind. We have received reports that YaNFD operates properly on Windows 10 (with minor changes -- see below) and macOS, but this has not been evaluated by the developers.

Installation

Install the YaNFD binary

go install github.com/named-data/YaNFD/cmd/yanfd@latest

Install YaNFD from Windows Store

Get it from: https://www.microsoft.com/store/apps/9NBK3ZJT4CL8

Install the configuration file

On MacOS/Linux

curl -o ./yanfd.toml https://raw.githubusercontent.com/named-data/YaNFD/master/yanfd.toml.sample
mkdir -p /usr/local/etc/ndn
install -m 644 ./yanfd.toml /usr/local/etc/ndn
rm ./yanfd.toml

On MacOS, one also needs to change socket_path to /var/run/nfd/nfd.sock in the copied configuration file.

On Windows 10/11

curl -o yanfd.toml https://raw.githubusercontent.com/named-data/YaNFD/master/yanfd.toml.sample
mkdir %APPDATA%\ndn
move yanfd.toml %APPDATA%\ndn\

One needs to change socket_path to ${TEMP}\\nfd\\nfd.sock in the copied configuration file. Also, to execute YaNFD on Windows 10, one needs to explicitly specify the configuration path:

yanfd.exe --config=%APPDATA%\ndn\yanfd.toml

Building from source

Linux, macOS, BSD

To build and install YaNFD on Unix-like platforms, run:

make
sudo make install

Windows 10

To build and install YaNFD on Windows, please run the go build command in the Makefile manually:

go build github.com/named-data/YaNFD/cmd/yanfd

At the moment, you will need to manually install the executable (yanfd.exe) and the configuration file (yanfd.toml.sample) to a location of your choice.

Configuration

YaNFD's configuration is split into two components: startup configuration and runtime configuration. Startup configuration sets default ports, queue sizes, logging levels, and other important options. Meanwhile, runtime configuration is used to create NDN faces, set routes and strategies, and other related tasks.

Startup configuration

Startup configuration for YaNFD is performed via a TOML file, by default read from /usr/local/etc/ndn/yanfd.toml on Unix-like systems. Note that you will need to copy the sample config file installed to /usr/local/etc/ndn/yanfd.toml.sample to this location before running YaNFD for the first time. The configuration options are documented via comments in the sample file.

On Windows, at this time, you will need to specify the location of the configuration file manually when starting YaNFD via the --config argument.

Runtime configuration

Runtime configuration is performed via the NFD Management Protocol. At the moment, this requires the installation of the NFD package to obtain the nfdc configuration utility. YaNFD supports the majority of this management protocol, but some features are currently unsupported, such as ContentStore management.

Running

To run YaNFD, run the yanfd (or yanfd.exe) executable. To view a list of available options, specify the --help argument.

After starting YaNFD, you can treat it like NFD from an application and configuration perspective.

Publications

yanfd's People

Contributors

amazingtapioca17 avatar danningyu avatar eric135 avatar pesa avatar pulsejet avatar yashlala avatar yoursunny avatar zjkmxy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

yanfd's Issues

WebSocket face frequently crashes when there are multiple connections

The error message.

panic: concurrent write to websocket connection

goroutine 2579 [running]:
github.com/gorilla/websocket.(*messageWriter).flushFrame(0xc000585af0, 0x1, {0xc0004c7ec0?, 0x2?, 0x2?})
        <SNIP>/Go/pkg/mod/github.com/gorilla/[email protected]/conn.go:617 +0x4b8
github.com/gorilla/websocket.(*Conn).WriteMessage(0xc0000fe580, 0xc00029c000?, {0xc0004c7ec0, 0x5c, 0x5c})
        <SNIP>/Go/pkg/mod/github.com/gorilla/[email protected]/conn.go:770 +0x127
github.com/named-data/YaNFD/face.(*WebSocketTransport).sendFrame(0xc00029c000, {0xc0004c7ec0, 0x5c, 0x5c})
        E:/YaNFD/face/web-socket-transport.go:67 +0xc5
github.com/named-data/YaNFD/face.sendPacket(0xc0000fe840, 0xc00038c8c0)
        E:/YaNFD/face/ndnlp-link-service.go:356 +0x5db
created by github.com/named-data/YaNFD/face.(*NDNLPLinkService).runSend in goroutine 1135
        E:/YaNFD/face/ndnlp-link-service.go:374 +0x3dd

Test machine is Windows 11.

Error while collecting status report (500).

I got this error when I check nfdc cs info (YaNFD run already)
Error while collecting status report (500).
CS information:
capacity=0
admit=off
serve=off
nEntries=0
nHits=0
nMisses=0
Do you have any recommendations to solve this?
Thank you

Opt-in to hacktoberfest

I'd like to contribute to this repository as part of Hacktoberfest. One feature I'd like to contribute is a WebSocket server, which enables web applications to connect to YaNFD just like how they work with NFD reference implementation.
In order for the Pull Requests to count toward my Hacktoberfest contributions, it is necessary for the maintainer to add hacktoberfest as a repository topic. Can you do that?
https://hacktoberfest.digitalocean.com/resources/maintainers

Concurrent map write for pitTokenMap

There is some concurrent map write in Pit. Maybe because expirationPitLoop runs in a separate goroutine

go pitCs.expirationPitLoop()

and this is not okay for the map deletion in RemoveInterest.

p.RemoveInterest(entry)

delete(p.pitTokenMap, e.token)

fatal error: concurrent map writes
goroutine 14 [running]:                                                                                                                                     runtime.throw({0x82a5ae?, 0x60?})
/snap/go/9605/src/runtime/panic.go:992 +0x71 fp=0xc00033c6d0 sp=0xc00033c6a0 pc=0x439a71                                                            runtime.mapdelete_fast32(0xc00033c778?, 0x1?, 0x1b5840bb)
/snap/go/9605/src/runtime/map_fast32.go:282 +0x2aa fp=0xc00033c718 sp=0xc00033c6d0 pc=0x41520a
github.com/named-data/YaNFD/table.(*PitCsTree).RemoveInterest(0xc000198e40?, {0x8cf988?, 0xc00340dc20?})
/home/vpatil/yanfd/table/pit-cs-tree.go:175 +0xee fp=0xc00033c740 sp=0xc00033c718 pc=0x58788e
github.com/named-data/YaNFD/table.(*PitCsTree).expirationPitLoop(0xc000198e40)
/home/vpatil/yanfd/table/pit-cs-tree.go:99 +0x196 fp=0xc00033c7c8 sp=0xc00033c740 pc=0x587096                                                       github.com/named-data/YaNFD/table.NewPitCS.func1()
/home/vpatil/yanfd/table/pit-cs-tree.go:77 +0x26 fp=0xc00033c7e0 sp=0xc00033c7c8 pc=0x586ec6                                                        runtime.goexit()
/snap/go/9605/src/runtime/asm_amd64.s:1571 +0x1 fp=0xc00033c7e8 sp=0xc00033c7e0 pc=0x469d01
created by github.com/named-data/YaNFD/table.NewPitCS
        /home/vpatil/yanfd/table/pit-cs-tree.go:77 +0x325

EDIT: sorry the log is a mess somehow

Invalid stale timer for content store

This issue was reported by @haowaiwai. The CS serves obsoleted data to MustBeFresh Interest.

Step to reproduce the result:

  • Start YaNFD
  • Run echo 111 | ndnpoke -f 500 -w 10000 /ndn/igw11
  • Run ndnpeek -p -f -w 10000 /ndn/igw11
  • The consumer received 111 and the producer quited.
  • After 1 sec, run ndnpeek -p -f -w 10000 /ndn/igw11 again
  • The ndnpeek consumer may return obsoleted data.

The reason is that current PitCSTree implementation has bugs so that it fails to set the current stale timer.

udp6 face creation not working

YaNFD version: a4132a8
nfdc version: 0.7.1-23-g6a699be8

  1. Bring up a network interface and assign an IPv6 ULA address:

    sudo ip link set enp94s0 up
    sudo ip addr replace fd54:450f:f5ac:807a::2/64 dev enp94s0
  2. Start YaNFD.

  3. Try to create a face:

    nfdc face create udp6://[fd54:450f:f5ac:807a::1]:6363

Expected: face creation succeeds.
Actual:

  • nfdc returns Error 406 when creating face: Unsupported scheme udp6
  • YaNFD log contains WARN[3207] [FaceMgmt] Unable to create unicast UDP face with URI udp6://[fd54:450f:f5ac:807a::1]:6363: Unsupported scheme udp6://[fd54:450f:f5ac:807a::1]:6363

ndn-tools broken with the merge of #49

I want to evaluate the improvement of #49 on next-gen hardware. I encountered different errors when trying to use ndnchunks and ndnping.

Validating these Errors

  • verified that the errors were non-existent with the previous build (v1.2.0) under the same conditions
  • found the same errors locally in a WSL (different) environment (Ubuntu 20.04 + Go 1.20.0)

Environment

Errors

ndnchunks

While ndncatchunks seemly did not stop, ndnputchunks produced the following:

Loading input ...
Published 1008 Data packets with prefix /data/v=1680565950959
ERROR: Failed to register prefix '/data' (Expecting ControlParameters element, but TLV has type 7)

ndnping

ndnpingserver produced the following:

PING SERVER /data
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<std::runtime_error> >'
  what():  Failed to register prefix: Internal error (Validator/policy did not invoke success or failure callback)
Aborted

Some dependencies of YaNFD are not being maintained

Don't know when these packages will stop working and we have to find alternatives, but they may happen in future. This issue is opened to mark this potential problem. No action needs to be done now.

`ether://` face creation not working

nfdc face create ether://[98:28:A6:3B:86:02] local dev://ens3

  • nfdc returns Error 406 when creating face: Unsupported scheme ether

  • YaNFD log contains WARN[3207] [FaceMgmt] Unable to create ether face with URI ether://[98:28:A6:3B:86:02]: Unsupported scheme ether://[]

Definition of canonical is confusing

The concept of canonical in YaNFD is confusing. For ethernetURI, fdURI, internalURI, nullURI, udpURI, canonical means well-formed:

YaNFD/ndn/uri.go

Lines 286 to 302 in 001755f

case ethernetURI:
isEthernet, _ := regexp.MatchString(macPattern, u.path)
return u.scheme == "ether" && isEthernet && u.port == 0
case fdURI:
fd, err := strconv.Atoi(u.path)
return u.scheme == "fd" && err == nil && fd >= 0 && u.port == 0
case internalURI:
return u.scheme == "internal" && u.path == "" && u.port == 0
case nullURI:
return u.scheme == "null" && u.path == "" && u.port == 0
case udpURI:
// Split off zone, if any
ip := net.ParseIP(u.PathHost())
// Port number is implicitly limited to <= 65535 by type uint16
// We have to test whether To16() && not IPv4 because the Go net library considers IPv4 addresses to be valid IPv6 addresses
isIPv4, _ := regexp.MatchString(ipv4Pattern, u.PathHost())
return ip != nil && ((u.scheme == "udp4" && ip.To4() != nil) || (u.scheme == "udp6" && ip.To16() != nil && !isIPv4)) && u.port > 0

For devURI and unixURI, canonical means existing interface, which is related to specific machine and operation system:

YaNFD/ndn/uri.go

Lines 303 to 306 in 001755f

case unixURI:
// Check whether file exists
fileInfo, err := os.Stat("/" + u.path)
return u.scheme == "unix" && ((err == nil && !fileInfo.IsDir()) || os.IsNotExist(err)) && u.port == 0

This restricts that the unit test can be only executed on specific machines:
uri := ndn.MakeUnixFaceURI("/run/nfd.sock")

Not every machine allows building program access to this path.

Note: ndn-cxx does not check the physical existence of interface in isCanonical.

Installation via pkg.go.dev

Version Discrepancy

The latest version of yanfd according to pkg.go.dev is v1.1.1 which was published on May 9, 2022. In contrast, the github (source) of yanfd states that the latest version is v1.1.0 published on April 21, 2022.

I believe this issue originated when moving the repository of yanfd from the account of @zjkmxy to the organization of @named-data. My justification for this is that the fork of zjkmxy has a tag called v1.1.1. I am not confidence how this issue can be handled. Releasing a version past v1.1.1 likely will not resolve the issue.

However, this is arguably an critical issue as users will be lead to install out-of-dated software thinking it is the updated version reflected on Github (where they are reading the README to install).

Installation Needs

When installing yanfd on a Ubuntu 20.04, Linux system according to the README. there were a series of errors that were resolved by installing extra dependencies not stated in the README. The following were the list of packages that I needed to install via apt before running YaNFD:

  • libpcap-dev
  • gcc/g++

Making this clear will ease installation for beginners.

Needed Released

There has been several changes to YaNFD that I believe warrant a upcoming release.

Most of the nfdc commands are not supported

I use the newest YaNFD compiled from Github source, and nfdc (v 0.7.1) also compile from Github source

most of the nfdc mgmt cmds fails with YaNFD, such as 'nfdc face', 'nfdc route' etc.

Logs here

root@75b4fe29f353:/generated# yanfd -version
YaNFD: Yet another NDN Forwarding Daemon
Version 0.0.1-cbcb2d1
Copyright (C) 2020-2021 Eric Newberry
Released under the terms of the MIT License
root@75b4fe29f353:/generated# nfdc --version
0.7.1
root@75b4fe29f353:/generated# nfdc face
Error 500 when querying face: Data Name has no segment number
root@75b4fe29f353:/generated# nfdc route
Error 500 when fetching RIB dataset: Data Name has no segment number
root@75b4fe29f353:/generated# nfdc status
Error while collecting status report (500).
General NFD status:
                version=
              startTime=19700101T000000
            currentTime=19700101T000000
                 uptime=0 seconds
       nNameTreeEntries=0
            nFibEntries=0
            nPitEntries=0
   nMeasurementsEntries=0
             nCsEntries=0
           nInInterests=0
          nOutInterests=0
                nInData=0
               nOutData=0
               nInNacks=0
              nOutNacks=0
    nSatisfiedInterests=0
  nUnsatisfiedInterests=0

YaNFD WebSocket face cannot recognize local browser

As shown in the following code:

t.makeTransportBase(remoteURI, localURI, PersistencyOnDemand, ndn.NonLocal, ndn.PointToPoint, tlv.MaxNDNPacketSize)

WebSocket connections are treated as remote connections blindly. This prevents any WebSocket connection from a local browser announcing routes.
However, the NFD wiki states:

Generally, the following faces are local:
...

  • WebSocket face whose remote address is a loopback address

NFD follows the instructions in the wiki and allows local WebSocket connections to announce routes via /localhost/nfd/rib/register command. We should fix YaNFD to make the behavior consistent.

SIGSEGV upon incoming UDP packet

When YaNFD version e12c571 receives an incoming UDP packet, it crashes with the following error:

  INFO[0003] [UnicastUDPTransport, FaceID=0, RemoteURI=udp4://192.168.94.0:6363, LocalURI=udp4://192.168.94.1:6363] state: Down -> Up
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x5f97c2]

goroutine 61 [running]:
github.com/Link512/stealthpool.(*Pool).tryPop(0x0)
        /go/pkg/mod/github.com/zjkmxy/[email protected]/pool.go:128 +0x42
github.com/Link512/stealthpool.(*Pool).Get(0x0)
        /go/pkg/mod/github.com/zjkmxy/[email protected]/pool.go:76 +0x4b
github.com/named-data/YaNFD/face.(*NDNLPLinkService).handleIncomingFrame(0xc00061e3c0, {0xc00039a500, 0x3d, 0x0?})
        /app/face/ndnlp-link-service.go:383 +0x36
github.com/named-data/YaNFD/face.(*UDPListener).Run(0xc0004b0240)
        /app/face/udp-listener.go:105 +0x5f1
created by github.com/named-data/YaNFD/executor.(*YaNFD).Start
        /app/executor/yanfd.go:203 +0x17aa

The cause is:

  • In NDNLPLinkService type, l.stealthPool is initialized in Run method and used in handleIncomingFrame method.
  • In UDPListener type, handleIncomingFrame is called before Run.

Summary on issues about PIT-CS

Background: #38 #40

  • Performance is 25-50% worse after putting expiration in the same thread. Maybe the map deletion is slow.
    Possible bottleneck:
    delete(curNode.parent.children, curNode.component.String())
  • Till now PIT tokens are shown to be used in any tests. Not sure if it is YaNFD's problem.
  • pitTokenMap seems to be wrong:
    pitTokenMap map[uint32]*nameTreePitEntry
  • csMap does not look good. It assumes the hashes have no conflict.
    csMap map[uint64]*nameTreeCsEntry

    index := p.hashCsName(data.Name())

Error that create the remote face with "nfdc face create remote tcp4://X.X.X.X:6363

The reason seems to be the remote YaNFD side. The TCP listener considers the remote URI of the new face as an UDP face (with RemoteURI=udp4://XX:6363, LocalUI=tcp4://XX:6363), and thus it is unable to maintain the connection.
I will investigate this problem but I'm not sure when I can fix it. If you are willing to, please open an issue on GitHub.

from the intranet:
nfdc face create remote tcp://120.53.13.74:6363
Error 406 when creating face: Transport error

the remote yanfd log:
WARN[0481] [FaceMgmt] Unable to create unicast TCP face with URI tcp4://120.53.13.74:6363:Unable to connect to remote endpoint: dial tcp4 :6363->120.53.13.74:6363: bind: address already in use

error when use nfdc face to see face list

I got this error when running nfdc face list
nfdc face
Error 500 when querying face: Dataset decoding failure: Expecting FaceStatus element, but TLV has type 105

YaNFD is the only forwarder that I used this time
Do you have any recommendations to solve this?
Thank you

go install: The go.mod file for the module providing named packages contains one or more replace directives.

go install command is failing because go.mod contains replace directives.
The replace directive should only be used during development.
It should be deleted for releases.

$ docker run -it --rm golang:1.18

root@8a297095e57f:/go# go install github.com/named-data/YaNFD/cmd/yanfd@latest
go: downloading github.com/named-data/YaNFD v1.1.0
go: github.com/named-data/YaNFD/cmd/yanfd@latest (in github.com/named-data/[email protected]):
        The go.mod file for the module providing named packages contains one or
        more replace directives. It must not contain directives that would cause
        it to be interpreted differently than if it were the main module.

root@8a297095e57f:/go# go install github.com/named-data/YaNFD/cmd/yanfd@master
go: downloading github.com/named-data/YaNFD v1.1.1-0.20220427100501-fcce5a0a157d
go: github.com/named-data/YaNFD/cmd/yanfd@master (in github.com/named-data/[email protected]):
        The go.mod file for the module providing named packages contains one or
        more replace directives. It must not contain directives that would cause
        it to be interpreted differently than if it were the main module.

YaNFD Route Issue

TL;DR

When an application face is closed, YaNFD may fail to remove the corresponding route.

Steps to reproduce the error

  1. Start YaNFD: sudo ./YaNFD
  2. Run python-ndn sample producer: pipenv run python examples/producer.py
  3. Run python-ndn sample consumer: pipenv run python examples/consumer.py
  4. Observe that the producer receives the Interest, and the consumer receives the Data.
  5. Shut down the producer by Ctrl+C.
  6. Restart the producer: pipenv run python examples/producer.py
  7. Run the consumer again: pipenv run python examples/consumer.py

Actual results

The producer does not receive the Interest. Consequently, the consumer cannot receive any Data.
The log of YaNFD is as follows:

  INFO[0000] [Main] Created UDP listener for fe80::7804:bb62:f6b7:cde9%utun1 on utun1
  INFO[0000] [Main] Created Unix stream listener for /var/run/nfd.sock
  INFO[0000] [UnixStreamListener, unix:///var/run/nfd.sock] Listening
  INFO[0006] [UnixStreamTransport, FaceID=0, RemoteURI=fd://1, LocalURI=unix:///var/run/nfd.sock] state: Down -> Up
  INFO[0006] [UnixStreamListener, unix:///var/run/nfd.sock] Accepting new Unix stream face fd://1
  INFO[0006] [RIBMgmt] Created route for Prefix=/example/testApp, FaceID=16, Origin=0, Cost=0, Flags=0x1
  INFO[0010] [UnixStreamTransport, FaceID=0, RemoteURI=fd://2, LocalURI=unix:///var/run/nfd.sock] state: Down -> Up
  INFO[0010] [UnixStreamListener, unix:///var/run/nfd.sock] Accepting new Unix stream face fd://2
  INFO[0010] [UnixStreamTransport, FaceID=17, RemoteURI=fd://2, LocalURI=unix:///var/run/nfd.sock] state: Up -> Down
  INFO[0010] [UnixStreamTransport, FaceID=17, RemoteURI=fd://2, LocalURI=unix:///var/run/nfd.sock] Closing Unix stream socket
  INFO[0015] [UnixStreamTransport, FaceID=16, RemoteURI=fd://1, LocalURI=unix:///var/run/nfd.sock] state: Up -> Down
  INFO[0015] [UnixStreamTransport, FaceID=16, RemoteURI=fd://1, LocalURI=unix:///var/run/nfd.sock] Closing Unix stream socket
  INFO[0021] [UnixStreamTransport, FaceID=0, RemoteURI=fd://3, LocalURI=unix:///var/run/nfd.sock] state: Down -> Up
  INFO[0021] [UnixStreamListener, unix:///var/run/nfd.sock] Accepting new Unix stream face fd://3
  INFO[0021] [RIBMgmt] Created route for Prefix=/example/testApp, FaceID=18, Origin=0, Cost=0, Flags=0x1
  INFO[0031] [UnixStreamTransport, FaceID=0, RemoteURI=fd://4, LocalURI=unix:///var/run/nfd.sock] state: Down -> Up
  INFO[0031] [UnixStreamListener, unix:///var/run/nfd.sock] Accepting new Unix stream face fd://4
 ERROR[0031] [FwThread-3] Non-existent nexthop FaceID=16 for Interest=/example/testApp/randomData/t=1625514215955 - DROP
  INFO[0037] [UnixStreamTransport, FaceID=19, RemoteURI=fd://4, LocalURI=unix:///var/run/nfd.sock] state: Up -> Down
  INFO[0037] [UnixStreamTransport, FaceID=19, RemoteURI=fd://4, LocalURI=unix:///var/run/nfd.sock] Closing Unix stream socket

FaceID 16 and 18 are producers, ID 17 and 19 are consumers.

Platform

Observed on MacOS Big Sur 11.4 and Windows 11 dev.

error while receiving data from socket (End of file)

when I check my nfdc route list it got output (the YaNFD running)
error while receiving data from socket (End of file)

but when I enter the command nfdc route list the YaNFD stopped with this on log

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x792f8d]

goroutine 7 [running]:
github.com/named-data/YaNFD/mgmt.(*RIBModule).list(0xc00017d350, 0xc00021af00, {0xc000210498, 0x6, 0x6}, 0x18?)
        /home/radara09/YaNFD/mgmt/rib.go:242 +0x44d
github.com/named-data/YaNFD/mgmt.(*RIBModule).handleIncomingInterest(0xc00017d350, 0xc00021af00, {0xc000210498, 0x6, 0x6}, 0x0?)
        /home/radara09/YaNFD/mgmt/rib.go:52 +0xc9
github.com/named-data/YaNFD/mgmt.(*Thread).Run(0xc00007a320)
        /home/radara09/YaNFD/mgmt/thread.go:143 +0x6bb
created by github.com/named-data/YaNFD/executor.(*YaNFD).Start
        /home/radara09/YaNFD/executor/yanfd.go:121 +0x15e

Do you have any recommendations to solve this?
Thank you

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.